From 284f0d364588821ba7e2ea0c42845fcbbf722290 Mon Sep 17 00:00:00 2001
From: daxpedda <1645124+daxpedda@users.noreply.github.com>
Date: Wed, 26 Dec 2018 18:19:46 +0100
Subject: [PATCH 01/16] Document that `-C opt-level=0` implies `-C
 debug-assertions`.

---
 src/doc/rustc/src/codegen-options/index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 94f21042c8fdd..a616409d9a400 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -187,7 +187,7 @@ This flag lets you control debug information:
 
 This flag lets you control the optimization level.
 
-* `0`: no optimizations
+* `0`: no optimizations, also turn on `cfg(debug_assertions)`.
 * `1`: basic optimizations
 * `2`: some optimizations
 * `3`: all optimizations

From 11b0fa21a66789c05471e2bc7ab58f5e40f4e6bd Mon Sep 17 00:00:00 2001
From: Philipp Hansch <dev@phansch.net>
Date: Sun, 30 Dec 2018 12:23:24 +0100
Subject: [PATCH 02/16] docs(rustc): Link to the book's source in rustc

---
 src/doc/rustc/src/contributing.md | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/doc/rustc/src/contributing.md b/src/doc/rustc/src/contributing.md
index 3a1cafe8a6153..25a5c97b0a120 100644
--- a/src/doc/rustc/src/contributing.md
+++ b/src/doc/rustc/src/contributing.md
@@ -1,6 +1,12 @@
 # Contributing to rustc
 
 We'd love to have your help improving `rustc`! To that end, we've written [a
-whole book](https://rust-lang.github.io/rustc-guide/) on its
+whole book][rustc_guide] on its
 internals, how it works, and how to get started working on it. To learn
 more, you'll want to check that out.
+
+If you would like to contribute to _this_ book, you can find its source in the
+rustc source at [src/doc/rustc][rustc_book].
+
+[rustc_guide]: https://rust-lang.github.io/rustc-guide/
+[rustc_book]: https://github.com/rust-lang/rust/tree/master/src/doc/rustc

From 6bae4a763df95c436ce9f1286b1d593e67218932 Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Thu, 3 Jan 2019 21:49:56 +0900
Subject: [PATCH 03/16] Fix unused_assignments false positive

Make `continue` jump to the loop condition's `LiveNode` instead of one
of the loop body.
---
 src/librustc/middle/liveness.rs       | 11 ++++++-----
 src/test/ui/liveness/liveness-dead.rs |  9 +++++++++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index a78cf1a471b4b..71a104ba6e761 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -911,7 +911,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     fn compute(&mut self, body: &hir::Expr) -> LiveNode {
-        // if there is a `break` or `again` at the top level, then it's
+        // if there is a `break` or `continue` at the top level, then it's
         // effectively a return---this only occurs in `for` loops,
         // where the body is really a closure.
 
@@ -1407,15 +1407,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         debug!("propagate_through_loop: using id for loop body {} {}",
                expr.id, self.ir.tcx.hir().node_to_pretty_string(body.id));
 
-        let break_ln = succ;
-        let cont_ln = ln;
-        self.break_ln.insert(expr.id, break_ln);
-        self.cont_ln.insert(expr.id, cont_ln);
+
+        self.break_ln.insert(expr.id, succ);
 
         let cond_ln = match kind {
             LoopLoop => ln,
             WhileLoop(ref cond) => self.propagate_through_expr(&cond, ln),
         };
+
+        self.cont_ln.insert(expr.id, cond_ln);
+
         let body_ln = self.propagate_through_block(body, cond_ln);
 
         // repeat until fixed point is reached:
diff --git a/src/test/ui/liveness/liveness-dead.rs b/src/test/ui/liveness/liveness-dead.rs
index 7d420afde4b72..004663c85ee50 100644
--- a/src/test/ui/liveness/liveness-dead.rs
+++ b/src/test/ui/liveness/liveness-dead.rs
@@ -27,4 +27,13 @@ fn f5(mut x: i32) {
     x = 4; //~ ERROR: value assigned to `x` is never read
 }
 
+// #22630
+fn f6() {
+    let mut done = false;
+    while !done {
+        done = true; // no error
+        continue;
+    }
+}
+
 fn main() {}

From 069b0c410808c1d1d33b495e048b1186e9f8d57f Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Thu, 3 Jan 2019 23:20:44 +0900
Subject: [PATCH 04/16] Cleanup

`for` loops are no longer closures.
---
 src/librustc/middle/liveness.rs | 20 +-------------------
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 71a104ba6e761..2ca823929fd38 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -911,17 +911,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     fn compute(&mut self, body: &hir::Expr) -> LiveNode {
-        // if there is a `break` or `continue` at the top level, then it's
-        // effectively a return---this only occurs in `for` loops,
-        // where the body is really a closure.
-
         debug!("compute: using id for body, {}", self.ir.tcx.hir().node_to_pretty_string(body.id));
 
-        let exit_ln = self.s.exit_ln;
-
-        self.break_ln.insert(body.id, exit_ln);
-        self.cont_ln.insert(body.id, exit_ln);
-
         // the fallthrough exit is only for those cases where we do not
         // explicitly return:
         let s = self.s;
@@ -1024,19 +1015,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 self.propagate_through_expr(&e, succ)
             }
 
-            hir::ExprKind::Closure(.., blk_id, _, _) => {
+            hir::ExprKind::Closure(..) => {
                 debug!("{} is an ExprKind::Closure",
                        self.ir.tcx.hir().node_to_pretty_string(expr.id));
 
-                // The next-node for a break is the successor of the entire
-                // loop. The next-node for a continue is the top of this loop.
-                let node = self.live_node(expr.hir_id, expr.span);
-
-                let break_ln = succ;
-                let cont_ln = node;
-                self.break_ln.insert(blk_id.node_id, break_ln);
-                self.cont_ln.insert(blk_id.node_id, cont_ln);
-
                 // the construction of a closure itself is not important,
                 // but we have to consider the closed over variables.
                 let caps = self.ir.capture_info_map.get(&expr.id).cloned().unwrap_or_else(||

From c120199116439827a89a0ac0f24f91f99dbed60f Mon Sep 17 00:00:00 2001
From: folex <0xdxdy@gmail.com>
Date: Sat, 5 Jan 2019 05:56:23 +0300
Subject: [PATCH 05/16] Show suggestion to use .char().nth() and link to The
 Book on unimplemented Index trait

---
 src/libcore/ops/index.rs           | 30 ++++++++++++++++++++++++++++++
 src/test/ui/str/str-idx.stderr     |  2 ++
 src/test/ui/str/str-mut-idx.stderr |  2 ++
 3 files changed, 34 insertions(+)

diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs
index 4f55c68ecd4ae..6cfa36741d0ca 100644
--- a/src/libcore/ops/index.rs
+++ b/src/libcore/ops/index.rs
@@ -51,6 +51,21 @@
 /// ```
 #[lang = "index"]
 #[rustc_on_unimplemented(
+    on(
+        _Self="&str",
+        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>"
+    ),
+    on(
+        _Self="str",
+        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>"
+    ),
+    on(
+        _Self="std::string::String",
+        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>"
+    ),
     message="the type `{Self}` cannot be indexed by `{Idx}`",
     label="`{Self}` cannot be indexed by `{Idx}`",
 )]
@@ -141,6 +156,21 @@ pub trait Index<Idx: ?Sized> {
 /// ```
 #[lang = "index_mut"]
 #[rustc_on_unimplemented(
+    on(
+        _Self="&str",
+        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>"
+    ),
+    on(
+        _Self="str",
+        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>"
+    ),
+    on(
+        _Self="std::string::String",
+        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>"
+    ),
     message="the type `{Self}` cannot be mutably indexed by `{Idx}`",
     label="`{Self}` cannot be mutably indexed by `{Idx}`",
 )]
diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr
index 108096df9c41c..71b1747492329 100644
--- a/src/test/ui/str/str-idx.stderr
+++ b/src/test/ui/str/str-idx.stderr
@@ -5,6 +5,8 @@ LL |     let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integ
    |                 ^^^^ `str` cannot be indexed by `{integer}`
    |
    = help: the trait `std::ops::Index<{integer}>` is not implemented for `str`
+   = 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: 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 a8ab38e5ab6a5..f1e969696b458 100644
--- a/src/test/ui/str/str-mut-idx.stderr
+++ b/src/test/ui/str/str-mut-idx.stderr
@@ -29,6 +29,8 @@ LL |     s[1usize] = bot();
    |     ^^^^^^^^^ `str` cannot be mutably indexed by `usize`
    |
    = help: the trait `std::ops::IndexMut<usize>` is not implemented for `str`
+   = 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: aborting due to 3 previous errors
 

From f4ded5b5591b3ec1446422dd9d62d404d4335753 Mon Sep 17 00:00:00 2001
From: Michael Bradshaw <mjbshaw@gmail.com>
Date: Mon, 24 Dec 2018 16:07:10 -0700
Subject: [PATCH 06/16] Add a regression test for mutating a non-mut
 #[thread_local]

---
 src/test/ui/thread-local-mutation.nll.stderr |  9 +++++++++
 src/test/ui/thread-local-mutation.rs         | 18 ++++++++++++++++++
 src/test/ui/thread-local-mutation.stderr     |  9 +++++++++
 3 files changed, 36 insertions(+)
 create mode 100644 src/test/ui/thread-local-mutation.nll.stderr
 create mode 100644 src/test/ui/thread-local-mutation.rs
 create mode 100644 src/test/ui/thread-local-mutation.stderr

diff --git a/src/test/ui/thread-local-mutation.nll.stderr b/src/test/ui/thread-local-mutation.nll.stderr
new file mode 100644
index 0000000000000..0a3664b0d9d40
--- /dev/null
+++ b/src/test/ui/thread-local-mutation.nll.stderr
@@ -0,0 +1,9 @@
+error[E0594]: cannot assign to immutable static item `S`
+  --> $DIR/thread-local-mutation.rs:11:5
+   |
+LL |     S = "after"; //~ ERROR cannot assign to immutable
+   |     ^^^^^^^^^^^ cannot assign
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.
diff --git a/src/test/ui/thread-local-mutation.rs b/src/test/ui/thread-local-mutation.rs
new file mode 100644
index 0000000000000..e738225ce2a48
--- /dev/null
+++ b/src/test/ui/thread-local-mutation.rs
@@ -0,0 +1,18 @@
+// Regression test for #54901: immutable thread locals could be mutated. See:
+// https://github.com/rust-lang/rust/issues/29594#issuecomment-328177697
+// https://github.com/rust-lang/rust/issues/54901
+
+#![feature(thread_local)]
+
+#[thread_local]
+static S: &str = "before";
+
+fn set_s() {
+    S = "after"; //~ ERROR cannot assign to immutable
+}
+
+fn main() {
+    println!("{}", S);
+    set_s();
+    println!("{}", S);
+}
diff --git a/src/test/ui/thread-local-mutation.stderr b/src/test/ui/thread-local-mutation.stderr
new file mode 100644
index 0000000000000..bf298523e1b73
--- /dev/null
+++ b/src/test/ui/thread-local-mutation.stderr
@@ -0,0 +1,9 @@
+error[E0594]: cannot assign to immutable thread-local static item
+  --> $DIR/thread-local-mutation.rs:11:5
+   |
+LL |     S = "after"; //~ ERROR cannot assign to immutable
+   |     ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.

From e5e9867f604b9f656d529deb04a6b99338770c9e Mon Sep 17 00:00:00 2001
From: AB1908 <abhishekbhattachejree@live.com>
Date: Tue, 15 Jan 2019 08:26:29 +0000
Subject: [PATCH 07/16] Pass a default value when unwrapping a span

Fixes #57323
---
 src/librustc_metadata/native_libs.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index d35d64957b7b4..1f00086e32fe1 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -163,7 +163,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> {
            !self.tcx.features().static_nobundle {
             feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
                                            "static_nobundle",
-                                           span.unwrap(),
+                                           span.unwrap_or_else(|| syntax_pos::DUMMY_SP),
                                            GateIssue::Language,
                                            "kind=\"static-nobundle\" is feature gated");
         }

From 93b55365b59767f87ac2a2e42876ad46210a0e55 Mon Sep 17 00:00:00 2001
From: Andy Russell <arussell123@gmail.com>
Date: Tue, 15 Jan 2019 11:27:58 -0500
Subject: [PATCH 08/16] use structured macro and path resolve suggestions

---
 src/librustc_resolve/lib.rs                   | 24 ++++++++++---
 src/test/ui/resolve/resolve-hint-macro.stderr |  2 +-
 ...uggest-path-instead-of-mod-dot-item.stderr | 36 ++++++++++++-------
 .../try-block/try-block-in-edition2015.stderr |  2 +-
 4 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index a25009ccfb49c..439d149227203 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3321,7 +3321,12 @@ impl<'a> Resolver<'a> {
             if let Some(def) = def {
                 match (def, source) {
                     (Def::Macro(..), _) => {
-                        err.span_label(span, format!("did you mean `{}!(...)`?", path_str));
+                        err.span_suggestion_with_applicability(
+                            span,
+                            "use `!` to invoke the macro",
+                            format!("{}!", path_str),
+                            Applicability::MaybeIncorrect,
+                        );
                         return (err, candidates);
                     }
                     (Def::TyAlias(..), PathSource::Trait(_)) => {
@@ -3333,13 +3338,22 @@ impl<'a> Resolver<'a> {
                     }
                     (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
                         ExprKind::Field(_, ident) => {
-                            err.span_label(parent.span, format!("did you mean `{}::{}`?",
-                                                                 path_str, ident));
+                            err.span_suggestion_with_applicability(
+                                parent.span,
+                                "use the path separator to refer to an item",
+                                format!("{}::{}", path_str, ident),
+                                Applicability::MaybeIncorrect,
+                            );
                             return (err, candidates);
                         }
                         ExprKind::MethodCall(ref segment, ..) => {
-                            err.span_label(parent.span, format!("did you mean `{}::{}(...)`?",
-                                                                 path_str, segment.ident));
+                            let span = parent.span.with_hi(segment.ident.span.hi());
+                            err.span_suggestion_with_applicability(
+                                span,
+                                "use the path separator to refer to an item",
+                                format!("{}::{}", path_str, segment.ident),
+                                Applicability::MaybeIncorrect,
+                            );
                             return (err, candidates);
                         }
                         _ => {}
diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr
index 4f6d0f695df44..ebe3c36f21eb1 100644
--- a/src/test/ui/resolve/resolve-hint-macro.stderr
+++ b/src/test/ui/resolve/resolve-hint-macro.stderr
@@ -2,7 +2,7 @@ error[E0423]: expected function, found macro `assert`
   --> $DIR/resolve-hint-macro.rs:2:5
    |
 LL |     assert(true);
-   |     ^^^^^^ did you mean `assert!(...)`?
+   |     ^^^^^^ help: use `!` to invoke the macro: `assert!`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
index 8a9426bfee862..b7b158ce7efa6 100644
--- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
+++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
@@ -4,15 +4,15 @@ error[E0423]: expected value, found module `a`
 LL |     a.I
    |     ^--
    |     |
-   |     did you mean `a::I`?
+   |     help: use the path separator to refer to an item: `a::I`
 
 error[E0423]: expected value, found module `a`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:22:5
    |
 LL |     a.g()
-   |     ^----
+   |     ^--
    |     |
-   |     did you mean `a::g(...)`?
+   |     help: use the path separator to refer to an item: `a::g`
 
 error[E0423]: expected value, found module `a`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5
@@ -20,16 +20,21 @@ error[E0423]: expected value, found module `a`
 LL |     a.b.J
    |     ^--
    |     |
-   |     did you mean `a::b`?
+   |     help: use the path separator to refer to an item: `a::b`
 
 error[E0423]: expected value, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:32:5
    |
 LL |     a::b.J
-   |     ^^^---
-   |     |  |
-   |     |  help: a constant with a similar name exists: `I`
-   |     did you mean `a::b::J`?
+   |     ^^^^
+help: a constant with a similar name exists
+   |
+LL |     a::I.J
+   |        ^
+help: use the path separator to refer to an item
+   |
+LL |     a::b::J
+   |
 
 error[E0423]: expected value, found module `a`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:37:5
@@ -37,7 +42,7 @@ error[E0423]: expected value, found module `a`
 LL |     a.b.f();
    |     ^--
    |     |
-   |     did you mean `a::b`?
+   |     help: use the path separator to refer to an item: `a::b`
 
 error[E0423]: expected value, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:40:12
@@ -51,10 +56,15 @@ error[E0423]: expected value, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5
    |
 LL |     a::b.f()
-   |     ^^^-----
-   |     |  |
-   |     |  help: a constant with a similar name exists: `I`
-   |     did you mean `a::b::f(...)`?
+   |     ^^^^
+help: a constant with a similar name exists
+   |
+LL |     a::I.f()
+   |        ^
+help: use the path separator to refer to an item
+   |
+LL |     a::b::f()
+   |     ^^^^^^^
 
 error[E0423]: expected value, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5
diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr
index 63650086bcaa9..a7b81060d3dc6 100644
--- a/src/test/ui/try-block/try-block-in-edition2015.stderr
+++ b/src/test/ui/try-block/try-block-in-edition2015.stderr
@@ -15,7 +15,7 @@ error[E0574]: expected struct, variant or union type, found macro `try`
   --> $DIR/try-block-in-edition2015.rs:4:33
    |
 LL |     let try_result: Option<_> = try {
-   |                                 ^^^ did you mean `try!(...)`?
+   |                                 ^^^ help: use `!` to invoke the macro: `try!`
 
 error: aborting due to 2 previous errors
 

From ae4b14e837b613febc9a7ccfee4230fb22044a10 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 16 Jan 2019 13:51:24 +1100
Subject: [PATCH 09/16] Use `Lit` rather than `P<Lit>` in `hir::ExprKind`.

It's simpler and makes some benchmark run up to 1% faster. It also makes
`hir::ExprKind` more like `ast::ExprKind` (which underwent the
equivalent change in #55777).
---
 src/librustc/hir/lowering.rs | 2 +-
 src/librustc/hir/mod.rs      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 8badcbfc1b301..8cdc493e6fda7 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -3775,7 +3775,7 @@ impl<'a> LoweringContext<'a> {
                 let ohs = P(self.lower_expr(ohs));
                 hir::ExprKind::Unary(op, ohs)
             }
-            ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((*l).clone())),
+            ExprKind::Lit(ref l) => hir::ExprKind::Lit((*l).clone()),
             ExprKind::Cast(ref expr, ref ty) => {
                 let expr = P(self.lower_expr(expr));
                 hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index fc4bd05476f6c..cf4bd27a0900a 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1466,7 +1466,7 @@ pub enum ExprKind {
     /// A unary operation (For example: `!x`, `*x`)
     Unary(UnOp, P<Expr>),
     /// A literal (For example: `1`, `"foo"`)
-    Lit(P<Lit>),
+    Lit(Lit),
     /// A cast (`foo as f64`)
     Cast(P<Expr>, P<Ty>),
     Type(P<Expr>, P<Ty>),

From dc455286205bc0b3be6a6c6dcefff0498a6f4bcf Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 16 Jan 2019 16:20:32 +1100
Subject: [PATCH 10/16] Remove `hir::Label`.

It's identical to `ast::Label`.
---
 src/librustc/hir/mod.rs       | 13 +------------
 src/librustc/ich/impls_hir.rs |  2 +-
 2 files changed, 2 insertions(+), 13 deletions(-)

diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index cf4bd27a0900a..aaef1c722be96 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -19,7 +19,7 @@ use syntax_pos::{Span, DUMMY_SP, symbol::InternedString};
 use syntax::source_map::{self, Spanned};
 use rustc_target::spec::abi::Abi;
 use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
-use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy};
+use syntax::ast::{Attribute, Label, Lit, StrStyle, FloatTy, IntTy, UintTy};
 use syntax::attr::InlineAttr;
 use syntax::ext::hygiene::SyntaxContext;
 use syntax::ptr::P;
@@ -142,17 +142,6 @@ pub const DUMMY_HIR_ID: HirId = HirId {
 
 pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
-pub struct Label {
-    pub ident: Ident,
-}
-
-impl fmt::Debug for Label {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "label({:?})", self.ident)
-    }
-}
-
 #[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
 pub struct Lifetime {
     pub id: NodeId,
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 8ff60e5f56225..f48059b328ff3 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -153,7 +153,7 @@ impl_stable_hash_for!(enum hir::LifetimeName {
     Error,
 });
 
-impl_stable_hash_for!(struct hir::Label {
+impl_stable_hash_for!(struct ast::Label {
     ident
 });
 

From 193809ec3ad035f45724f31328142f38a4e9f66a Mon Sep 17 00:00:00 2001
From: AB1908 <abhishekbhattachejree@live.com>
Date: Wed, 16 Jan 2019 05:32:03 +0000
Subject: [PATCH 11/16] Add regression test to close #53787

---
 .../ui/issue-53787-inline-assembler-macro.rs  | 24 +++++++++++++++++++
 .../issue-53787-inline-assembler-macro.stderr |  9 +++++++
 2 files changed, 33 insertions(+)
 create mode 100644 src/test/ui/issue-53787-inline-assembler-macro.rs
 create mode 100644 src/test/ui/issue-53787-inline-assembler-macro.stderr

diff --git a/src/test/ui/issue-53787-inline-assembler-macro.rs b/src/test/ui/issue-53787-inline-assembler-macro.rs
new file mode 100644
index 0000000000000..4f1048f787dab
--- /dev/null
+++ b/src/test/ui/issue-53787-inline-assembler-macro.rs
@@ -0,0 +1,24 @@
+// Regression test for Issue #53787: Fix ICE when creating a label in inline assembler with macros.
+
+#![feature(asm)]
+
+macro_rules! fake_jump {
+    ($id:expr) => {
+        unsafe {
+            
+            asm!(
+            "
+            jmp $0
+            lea eax, [ebx]
+            xor eax, 0xDEADBEEF
+            retn
+            $0:
+            "::"0"($id)::"volatile", "intel");
+        }
+    };
+}
+
+fn main() {
+    fake_jump!("FirstFunc"); //~ ERROR invalid value for constraint in inline assembly
+    println!("Hello, world!");
+}
diff --git a/src/test/ui/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issue-53787-inline-assembler-macro.stderr
new file mode 100644
index 0000000000000..f63b2e1932754
--- /dev/null
+++ b/src/test/ui/issue-53787-inline-assembler-macro.stderr
@@ -0,0 +1,9 @@
+error[E0669]: invalid value for constraint in inline assembly
+  --> $DIR/issue-53787-inline-assembler-macro.rs:22:16
+   |
+LL |     fake_jump!("FirstFunc"); //~ ERROR invalid value for constraint in inline assembly
+   |                ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0669`.

From 3f0a75d80619e99e849c10fde406da4109db9e29 Mon Sep 17 00:00:00 2001
From: AB1908 <abhishekbhattachejree@live.com>
Date: Wed, 16 Jan 2019 06:29:44 +0000
Subject: [PATCH 12/16] Remove trailing whitespace

---
 src/test/ui/issue-53787-inline-assembler-macro.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/test/ui/issue-53787-inline-assembler-macro.rs b/src/test/ui/issue-53787-inline-assembler-macro.rs
index 4f1048f787dab..937bce1b655dd 100644
--- a/src/test/ui/issue-53787-inline-assembler-macro.rs
+++ b/src/test/ui/issue-53787-inline-assembler-macro.rs
@@ -5,7 +5,6 @@
 macro_rules! fake_jump {
     ($id:expr) => {
         unsafe {
-            
             asm!(
             "
             jmp $0

From 0edc5c9779cbe5a3d244f3915ebb05813973e592 Mon Sep 17 00:00:00 2001
From: AB1908 <abhishekbhattachejree@live.com>
Date: Wed, 16 Jan 2019 23:08:42 +0000
Subject: [PATCH 13/16] Fix error template

---
 src/test/ui/issue-53787-inline-assembler-macro.stderr | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/ui/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issue-53787-inline-assembler-macro.stderr
index f63b2e1932754..69f380bdc9c03 100644
--- a/src/test/ui/issue-53787-inline-assembler-macro.stderr
+++ b/src/test/ui/issue-53787-inline-assembler-macro.stderr
@@ -1,5 +1,5 @@
 error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/issue-53787-inline-assembler-macro.rs:22:16
+  --> $DIR/issue-53787-inline-assembler-macro.rs:21:16
    |
 LL |     fake_jump!("FirstFunc"); //~ ERROR invalid value for constraint in inline assembly
    |                ^^^^^^^^^^^

From 1e3f475d643603b9570710b13e20de587a22a5ea Mon Sep 17 00:00:00 2001
From: AB1908 <abhishekbhattachejree@live.com>
Date: Thu, 17 Jan 2019 03:40:36 +0000
Subject: [PATCH 14/16] Add test for linking non-existent static library

---
 src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs | 6 ++++++
 .../ui/feature-gate/feature-gate-static-nobundle-2.stderr  | 7 +++++++
 2 files changed, 13 insertions(+)
 create mode 100644 src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs
 create mode 100644 src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr

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
new file mode 100644
index 0000000000000..92844f9306d28
--- /dev/null
+++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs
@@ -0,0 +1,6 @@
+//~ ERROR kind="static-nobundle" is feature gated
+// Test the behavior of rustc when non-existent library is statically linked
+
+// compile-flags: -l static-nobundle=nonexistent
+
+fn main() {}
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
new file mode 100644
index 0000000000000..419c21901a02f
--- /dev/null
+++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr
@@ -0,0 +1,7 @@
+error[E0658]: kind="static-nobundle" is feature gated (see issue #37403)
+   |
+   = help: add #![feature(static_nobundle)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.

From e3ba6ed3f571119e2f9165805e77c20b5e7a14b4 Mon Sep 17 00:00:00 2001
From: Dan Robertson <dan@dlrobertson.com>
Date: Thu, 17 Jan 2019 13:53:21 +0000
Subject: [PATCH 15/16] Fix suggestions given mulitple bad lifetimes

When given multiple lifetimes prior to type parameters in generic
parameters, do not ICE and print the correct suggestion.
---
 src/librustc_errors/lib.rs                    |  9 ++--
 src/libsyntax/parse/parser.rs                 | 21 +++------
 src/test/ui/lifetime-before-type-params.rs    |  9 ++++
 .../ui/lifetime-before-type-params.stderr     | 47 +++++++++++++++++++
 .../suggestions/suggest-move-lifetimes.stderr |  4 +-
 5 files changed, 69 insertions(+), 21 deletions(-)
 create mode 100644 src/test/ui/lifetime-before-type-params.rs
 create mode 100644 src/test/ui/lifetime-before-type-params.stderr

diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index a074441f8a179..3e25f98ccd27c 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -135,10 +135,11 @@ impl CodeSuggestion {
             if let Some(line) = line_opt {
                 if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) {
                     let hi_opt = hi_opt.and_then(|hi| line.char_indices().map(|(i, _)| i).nth(hi));
-                    buf.push_str(match hi_opt {
-                        Some(hi) => &line[lo..hi],
-                        None => &line[lo..],
-                    });
+                    match hi_opt {
+                        Some(hi) if hi > lo => buf.push_str(&line[lo..hi]),
+                        Some(_) => (),
+                        None => buf.push_str(&line[lo..]),
+                    }
                 }
                 if let None = hi_opt {
                     buf.push('\n');
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 823c786bded26..5b430d13516b4 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5234,22 +5234,13 @@ impl<'a> Parser<'a> {
                     kind: ast::GenericParamKind::Lifetime,
                 });
                 if let Some(sp) = seen_ty_param {
-                    let param_span = self.prev_span;
-                    let ate_comma = self.eat(&token::Comma);
-                    let remove_sp = if ate_comma {
-                        param_span.until(self.span)
-                    } else {
-                        last_comma_span.unwrap_or(param_span).to(param_span)
-                    };
-                    bad_lifetime_pos.push(param_span);
-
-                    if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
+                    let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span);
+                    bad_lifetime_pos.push(self.prev_span);
+                    if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) {
                         suggestions.push((remove_sp, String::new()));
-                        suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
-                    }
-                    if ate_comma {
-                        last_comma_span = Some(self.prev_span);
-                        continue
+                        suggestions.push((
+                            sp.shrink_to_lo(),
+                            format!("{}, ", snippet)));
                     }
                 }
             } else if self.check_ident() {
diff --git a/src/test/ui/lifetime-before-type-params.rs b/src/test/ui/lifetime-before-type-params.rs
new file mode 100644
index 0000000000000..9b905d4883a16
--- /dev/null
+++ b/src/test/ui/lifetime-before-type-params.rs
@@ -0,0 +1,9 @@
+#![allow(unused)]
+fn first<T, 'a, 'b>() {}
+//~^ ERROR lifetime parameters must be declared prior to type parameters
+fn second<'a, T, 'b>() {}
+//~^ ERROR lifetime parameters must be declared prior to type parameters
+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
diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr
new file mode 100644
index 0000000000000..7ac8dffdfbe0c
--- /dev/null
+++ b/src/test/ui/lifetime-before-type-params.stderr
@@ -0,0 +1,47 @@
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/lifetime-before-type-params.rs:2:13
+   |
+LL | fn first<T, 'a, 'b>() {}
+   |             ^^  ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | fn first<'a, 'b, T>() {}
+   |          ^^^ ^^^ --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/lifetime-before-type-params.rs:4:18
+   |
+LL | fn second<'a, T, 'b>() {}
+   |                  ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | fn second<'a, 'b, T>() {}
+   |               ^^^ --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/lifetime-before-type-params.rs:6:16
+   |
+LL | fn third<T, U, 'a>() {}
+   |                ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | fn third<'a, T, U>() {}
+   |          ^^^    --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/lifetime-before-type-params.rs:8:18
+   |
+LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
+   |                  ^^     ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | fn fourth<'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
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
index 72a2cbe6bf6de..b36e927b5c0c6 100644
--- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
@@ -16,7 +16,7 @@ LL | struct B<T, 'a, U> { //~ ERROR lifetime parameters must be declared
 help: move the lifetime parameter prior to the first type parameter
    |
 LL | struct B<'a, T, U> { //~ ERROR lifetime parameters must be declared
-   |          ^^^   --
+   |          ^^^ --
 
 error: lifetime parameters must be declared prior to type parameters
   --> $DIR/suggest-move-lifetimes.rs:10:16
@@ -36,7 +36,7 @@ LL | struct D<T, U, 'a, 'b, V, 'c> { //~ ERROR lifetime parameters must be decla
 help: move the lifetime parameter prior to the first type parameter
    |
 LL | struct D<'a, 'b, 'c, T, U, V> { //~ ERROR lifetime parameters must be declared
-   |          ^^^ ^^^ ^^^      ---
+   |          ^^^ ^^^ ^^^    -- --
 
 error: aborting due to 4 previous errors
 

From ec3c5b0199045b3ae3959631998451543bd99518 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 17 Jan 2019 21:19:30 -0800
Subject: [PATCH 16/16] Use structured suggestion to surround struct literal
 with parenthesis

---
 src/librustc_resolve/lib.rs          | 42 ++++++++++++++++++++++++----
 src/test/ui/error-codes/E0423.stderr | 12 ++++++--
 2 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 39be3cb744080..430edcafae26a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3369,6 +3369,29 @@ impl<'a> Resolver<'a> {
                                 Ok(ref snippet) if snippet == "{" => true,
                                 _ => false,
                             };
+                            // In case this could be a struct literal that needs to be surrounded
+                            // by parenthesis, find the appropriate span.
+                            let mut i = 0;
+                            let mut closing_brace = None;
+                            loop {
+                                sp = sm.next_point(sp);
+                                match sm.span_to_snippet(sp) {
+                                    Ok(ref snippet) => {
+                                        if snippet == "}" {
+                                            let sp = span.to(sp);
+                                            if let Ok(snippet) = sm.span_to_snippet(sp) {
+                                                closing_brace = Some((sp, snippet));
+                                            }
+                                            break;
+                                        }
+                                    }
+                                    _ => break,
+                                }
+                                i += 1;
+                                if i > 100 { // The bigger the span the more likely we're
+                                    break;   // incorrect. Bound it to 100 chars long.
+                                }
+                            }
                             match source {
                                 PathSource::Expr(Some(parent)) => {
                                     match parent.node {
@@ -3395,11 +3418,20 @@ impl<'a> Resolver<'a> {
                                     }
                                 },
                                 PathSource::Expr(None) if followed_by_brace == true => {
-                                    err.span_label(
-                                        span,
-                                        format!("did you mean `({} {{ /* fields */ }})`?",
-                                                path_str),
-                                    );
+                                    if let Some((sp, snippet)) = closing_brace {
+                                        err.span_suggestion_with_applicability(
+                                            sp,
+                                            "surround the struct literal with parenthesis",
+                                            format!("({})", snippet),
+                                            Applicability::MaybeIncorrect,
+                                        );
+                                    } else {
+                                        err.span_label(
+                                            span,
+                                            format!("did you mean `({} {{ /* fields */ }})`?",
+                                                    path_str),
+                                        );
+                                    }
                                     return (err, candidates);
                                 },
                                 _ => {
diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr
index df9ed631a1c2e..3f3c78c68d097 100644
--- a/src/test/ui/error-codes/E0423.stderr
+++ b/src/test/ui/error-codes/E0423.stderr
@@ -29,19 +29,25 @@ error[E0423]: expected value, found struct `S`
   --> $DIR/E0423.rs:12:32
    |
 LL |     if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
-   |                                ^ did you mean `(S { /* fields */ })`?
+   |                                ^---------------
+   |                                |
+   |                                help: surround the struct literal with parenthesis: `(S { x: 1, y: 2 })`
 
 error[E0423]: expected value, found struct `T`
   --> $DIR/E0423.rs:15:8
    |
 LL |     if T {} == T {} { println!("Ok"); }
-   |        ^ did you mean `(T { /* fields */ })`?
+   |        ^---
+   |        |
+   |        help: surround the struct literal with parenthesis: `(T {})`
 
 error[E0423]: expected value, found struct `std::ops::Range`
   --> $DIR/E0423.rs:21:14
    |
 LL |     for _ in std::ops::Range { start: 0, end: 10 } {}
-   |              ^^^^^^^^^^^^^^^ did you mean `(std::ops::Range { /* fields */ })`?
+   |              ^^^^^^^^^^^^^^^----------------------
+   |              |
+   |              help: surround the struct literal with parenthesis: `(std::ops::Range { start: 0, end: 10 })`
 
 error: aborting due to 7 previous errors