about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-23 21:44:37 +0000
committerbors <bors@rust-lang.org>2018-07-23 21:44:37 +0000
commit6a1c0637ce44aeea6c60527f4c0e7fb33f2bcd0d (patch)
tree25e3c072744828f6dbfceb3a09c0328176e5afbb /src
parent00204c2f52ec0280bda17de347c79f88e9c6b479 (diff)
parent8ec9d7242c3352fbc617d907bec3632215811356 (diff)
downloadrust-6a1c0637ce44aeea6c60527f4c0e7fb33f2bcd0d.tar.gz
rust-6a1c0637ce44aeea6c60527f4c0e7fb33f2bcd0d.zip
Auto merge of #52175 - fpoli:testsuite-callsite-span, r=petrochenkov
Match errors using the callsite of macro expansions

Fix for issue #51848
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/codemap_tests/bad-format-args.rs6
-rw-r--r--src/test/ui/codemap_tests/bad-format-args.stderr6
-rw-r--r--src/test/ui/cross-crate-macro-backtrace/main.rs3
-rw-r--r--src/test/ui/cross-crate-macro-backtrace/main.stderr2
-rw-r--r--src/test/ui/cross-file-errors/main.rs1
-rw-r--r--src/test/ui/edition-keywords-2015-2018-expansion.rs2
-rw-r--r--src/test/ui/edition-keywords-2015-2018-expansion.stderr2
-rw-r--r--src/test/ui/edition-keywords-2018-2018-expansion.rs2
-rw-r--r--src/test/ui/edition-keywords-2018-2018-expansion.stderr2
-rw-r--r--src/test/ui/hygiene/intercrate.rs3
-rw-r--r--src/test/ui/hygiene/intercrate.stderr2
-rw-r--r--src/test/ui/hygiene/local_inner_macros_disabled.rs3
-rw-r--r--src/test/ui/hygiene/local_inner_macros_disabled.stderr4
-rw-r--r--src/test/ui/issue-13446.rs3
-rw-r--r--src/test/ui/issue-13446.stderr2
-rw-r--r--src/test/ui/issue-16966.rs6
-rw-r--r--src/test/ui/issue-16966.stderr8
-rw-r--r--src/test/ui/issue-32829.rs3
-rw-r--r--src/test/ui/issue-32829.stderr2
-rw-r--r--src/test/ui/issue-50577.rs1
-rw-r--r--src/test/ui/issue-51848.rs30
-rw-r--r--src/test/ui/issue-51848.stderr21
-rw-r--r--src/test/ui/lifetimes/borrowck-let-suggestion.nll.stderr1
-rw-r--r--src/test/ui/lifetimes/borrowck-let-suggestion.rs1
-rw-r--r--src/test/ui/lifetimes/borrowck-let-suggestion.stderr2
-rw-r--r--src/test/ui/reachable/expr_again.rs1
-rw-r--r--src/test/ui/reachable/expr_block.rs1
-rw-r--r--src/test/ui/reachable/expr_if.rs1
-rw-r--r--src/test/ui/reachable/expr_loop.rs3
-rw-r--r--src/test/ui/reachable/expr_loop.stderr4
-rw-r--r--src/test/ui/reachable/expr_match.rs2
-rw-r--r--src/test/ui/reachable/expr_match.stderr2
-rw-r--r--src/test/ui/reachable/expr_while.rs3
-rw-r--r--src/test/ui/reachable/expr_while.stderr4
-rw-r--r--src/test/ui/span/coerce-suggestions.rs1
-rw-r--r--src/test/ui/span/issue-33884.rs1
-rw-r--r--src/test/ui/span/slice-borrow.nll.stderr2
-rw-r--r--src/test/ui/span/slice-borrow.rs1
-rw-r--r--src/test/ui/span/slice-borrow.stderr2
-rw-r--r--src/test/ui/type-check/cannot_infer_local_or_vec.rs1
-rw-r--r--src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.rs1
-rw-r--r--src/tools/compiletest/src/json.rs32
-rw-r--r--src/tools/compiletest/src/runtest.rs6
43 files changed, 137 insertions, 49 deletions
diff --git a/src/test/ui/codemap_tests/bad-format-args.rs b/src/test/ui/codemap_tests/bad-format-args.rs
index de7bc88f9ba..df7d5fe927e 100644
--- a/src/test/ui/codemap_tests/bad-format-args.rs
+++ b/src/test/ui/codemap_tests/bad-format-args.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    format!();
-    format!("" 1);
-    format!("", 1 1);
+    format!(); //~ ERROR requires at least a format string argument
+    format!("" 1); //~ ERROR expected token: `,`
+    format!("", 1 1); //~ ERROR expected token: `,`
 }
diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr
index 5414557ddc2..d0cdeb2178f 100644
--- a/src/test/ui/codemap_tests/bad-format-args.stderr
+++ b/src/test/ui/codemap_tests/bad-format-args.stderr
@@ -1,7 +1,7 @@
 error: requires at least a format string argument
   --> $DIR/bad-format-args.rs:12:5
    |
-LL |     format!();
+LL |     format!(); //~ ERROR requires at least a format string argument
    |     ^^^^^^^^^^
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
@@ -9,7 +9,7 @@ LL |     format!();
 error: expected token: `,`
   --> $DIR/bad-format-args.rs:13:5
    |
-LL |     format!("" 1);
+LL |     format!("" 1); //~ ERROR expected token: `,`
    |     ^^^^^^^^^^^^^^
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
@@ -17,7 +17,7 @@ LL |     format!("" 1);
 error: expected token: `,`
   --> $DIR/bad-format-args.rs:14:5
    |
-LL |     format!("", 1 1);
+LL |     format!("", 1 1); //~ ERROR expected token: `,`
    |     ^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/src/test/ui/cross-crate-macro-backtrace/main.rs b/src/test/ui/cross-crate-macro-backtrace/main.rs
index 85640087a9d..9a6fa3e6920 100644
--- a/src/test/ui/cross-crate-macro-backtrace/main.rs
+++ b/src/test/ui/cross-crate-macro-backtrace/main.rs
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: in format string
-
 // aux-build:extern_macro_crate.rs
 #[macro_use(myprintln, myprint)]
 extern crate extern_macro_crate;
 
 fn main() {
     myprintln!("{}");
+    //~^ ERROR in format string
 }
diff --git a/src/test/ui/cross-crate-macro-backtrace/main.stderr b/src/test/ui/cross-crate-macro-backtrace/main.stderr
index ab447d07241..bffd76ca587 100644
--- a/src/test/ui/cross-crate-macro-backtrace/main.stderr
+++ b/src/test/ui/cross-crate-macro-backtrace/main.stderr
@@ -1,5 +1,5 @@
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/main.rs:18:5
+  --> $DIR/main.rs:16:5
    |
 LL |     myprintln!("{}");
    |     ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/cross-file-errors/main.rs b/src/test/ui/cross-file-errors/main.rs
index 8eae79a21a9..659075acd88 100644
--- a/src/test/ui/cross-file-errors/main.rs
+++ b/src/test/ui/cross-file-errors/main.rs
@@ -13,4 +13,5 @@ mod underscore;
 
 fn main() {
     underscore!();
+    //~^ ERROR expected expression, found reserved identifier `_`
 }
diff --git a/src/test/ui/edition-keywords-2015-2018-expansion.rs b/src/test/ui/edition-keywords-2015-2018-expansion.rs
index 082eb8d89f9..41d5ebd3e7d 100644
--- a/src/test/ui/edition-keywords-2015-2018-expansion.rs
+++ b/src/test/ui/edition-keywords-2015-2018-expansion.rs
@@ -17,7 +17,7 @@
 extern crate edition_kw_macro_2018;
 
 mod one_async {
-    produces_async! {} // ERROR expected identifier, found reserved keyword
+    produces_async! {} //~ ERROR expected identifier, found reserved keyword
 }
 mod two_async {
     produces_async_raw! {} // OK
diff --git a/src/test/ui/edition-keywords-2015-2018-expansion.stderr b/src/test/ui/edition-keywords-2015-2018-expansion.stderr
index 13c4ee82537..5852d56e6d3 100644
--- a/src/test/ui/edition-keywords-2015-2018-expansion.stderr
+++ b/src/test/ui/edition-keywords-2015-2018-expansion.stderr
@@ -1,7 +1,7 @@
 error: expected identifier, found reserved keyword `async`
   --> $DIR/edition-keywords-2015-2018-expansion.rs:20:5
    |
-LL |     produces_async! {} // ERROR expected identifier, found reserved keyword
+LL |     produces_async! {} //~ ERROR expected identifier, found reserved keyword
    |     ^^^^^^^^^^^^^^^^^^ expected identifier, found reserved keyword
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/src/test/ui/edition-keywords-2018-2018-expansion.rs b/src/test/ui/edition-keywords-2018-2018-expansion.rs
index 50db4202e98..a1ae1b5d004 100644
--- a/src/test/ui/edition-keywords-2018-2018-expansion.rs
+++ b/src/test/ui/edition-keywords-2018-2018-expansion.rs
@@ -17,7 +17,7 @@
 extern crate edition_kw_macro_2018;
 
 mod one_async {
-    produces_async! {} // ERROR expected identifier, found reserved keyword `async`
+    produces_async! {} //~ ERROR expected identifier, found reserved keyword `async`
 }
 mod two_async {
     produces_async_raw! {} // OK
diff --git a/src/test/ui/edition-keywords-2018-2018-expansion.stderr b/src/test/ui/edition-keywords-2018-2018-expansion.stderr
index cd51030fd28..91d0b2d30b5 100644
--- a/src/test/ui/edition-keywords-2018-2018-expansion.stderr
+++ b/src/test/ui/edition-keywords-2018-2018-expansion.stderr
@@ -1,7 +1,7 @@
 error: expected identifier, found reserved keyword `async`
   --> $DIR/edition-keywords-2018-2018-expansion.rs:20:5
    |
-LL |     produces_async! {} // ERROR expected identifier, found reserved keyword `async`
+LL |     produces_async! {} //~ ERROR expected identifier, found reserved keyword `async`
    |     ^^^^^^^^^^^^^^^^^^ expected identifier, found reserved keyword
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/src/test/ui/hygiene/intercrate.rs b/src/test/ui/hygiene/intercrate.rs
index 50fc985ba34..f27eed59b8f 100644
--- a/src/test/ui/hygiene/intercrate.rs
+++ b/src/test/ui/hygiene/intercrate.rs
@@ -12,12 +12,11 @@
 
 // aux-build:intercrate.rs
 
-// error-pattern:type `fn() -> u32 {intercrate::foo::bar::f}` is private
-
 #![feature(decl_macro)]
 
 extern crate intercrate;
 
 fn main() {
     assert_eq!(intercrate::foo::m!(), 1);
+    //~^ ERROR type `fn() -> u32 {intercrate::foo::bar::f}` is private
 }
diff --git a/src/test/ui/hygiene/intercrate.stderr b/src/test/ui/hygiene/intercrate.stderr
index ecbc6e7b147..b0792412aa0 100644
--- a/src/test/ui/hygiene/intercrate.stderr
+++ b/src/test/ui/hygiene/intercrate.stderr
@@ -1,5 +1,5 @@
 error: type `fn() -> u32 {intercrate::foo::bar::f}` is private
-  --> $DIR/intercrate.rs:22:16
+  --> $DIR/intercrate.rs:20:16
    |
 LL |     assert_eq!(intercrate::foo::m!(), 1);
    |                ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/hygiene/local_inner_macros_disabled.rs b/src/test/ui/hygiene/local_inner_macros_disabled.rs
index 00b38787db8..0a4bdb74807 100644
--- a/src/test/ui/hygiene/local_inner_macros_disabled.rs
+++ b/src/test/ui/hygiene/local_inner_macros_disabled.rs
@@ -11,11 +11,10 @@
 // `local_inner_macros` has no effect if `feature(use_extern_macros)` is not enabled
 
 // aux-build:local_inner_macros.rs
-// error-pattern: cannot find macro `helper2!` in this scope
 
 #[macro_use(public_macro)]
 extern crate local_inner_macros;
 
-public_macro!();
+public_macro!(); //~ ERROR cannot find macro `helper2!` in this scope
 
 fn main() {}
diff --git a/src/test/ui/hygiene/local_inner_macros_disabled.stderr b/src/test/ui/hygiene/local_inner_macros_disabled.stderr
index 64cb6c400cf..3dcd03b6f42 100644
--- a/src/test/ui/hygiene/local_inner_macros_disabled.stderr
+++ b/src/test/ui/hygiene/local_inner_macros_disabled.stderr
@@ -1,7 +1,7 @@
 error: cannot find macro `helper2!` in this scope
-  --> $DIR/local_inner_macros_disabled.rs:19:1
+  --> $DIR/local_inner_macros_disabled.rs:18:1
    |
-LL | public_macro!();
+LL | public_macro!(); //~ ERROR cannot find macro `helper2!` in this scope
    | ^^^^^^^^^^^^^^^^
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/src/test/ui/issue-13446.rs b/src/test/ui/issue-13446.rs
index 6ad3ec67b29..6607e1903b6 100644
--- a/src/test/ui/issue-13446.rs
+++ b/src/test/ui/issue-13446.rs
@@ -11,8 +11,7 @@
 
 // Used to cause ICE
 
-// error-pattern: mismatched types
-
 static VEC: [u32; 256] = vec![];
+//~^ ERROR mismatched types
 
 fn main() {}
diff --git a/src/test/ui/issue-13446.stderr b/src/test/ui/issue-13446.stderr
index 68fece30c81..110bb4b83db 100644
--- a/src/test/ui/issue-13446.stderr
+++ b/src/test/ui/issue-13446.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-13446.rs:16:26
+  --> $DIR/issue-13446.rs:14:26
    |
 LL | static VEC: [u32; 256] = vec![];
    |                          ^^^^^^ expected array of 256 elements, found struct `std::vec::Vec`
diff --git a/src/test/ui/issue-16966.rs b/src/test/ui/issue-16966.rs
index ecf81c8af17..38b102c7e3e 100644
--- a/src/test/ui/issue-16966.rs
+++ b/src/test/ui/issue-16966.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:type annotations needed
 fn main() {
-    panic!(
-        std::default::Default::default()
-    );
+    panic!(std::default::Default::default());
+    //~^ ERROR type annotations needed
 }
diff --git a/src/test/ui/issue-16966.stderr b/src/test/ui/issue-16966.stderr
index f7129a6fe1b..a26910e0146 100644
--- a/src/test/ui/issue-16966.stderr
+++ b/src/test/ui/issue-16966.stderr
@@ -1,10 +1,8 @@
 error[E0282]: type annotations needed
-  --> $DIR/issue-16966.rs:13:5
+  --> $DIR/issue-16966.rs:12:5
    |
-LL | /     panic!(
-LL | |         std::default::Default::default()
-LL | |     );
-   | |______^ cannot infer type for `M`
+LL |     panic!(std::default::Default::default());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `M`
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
diff --git a/src/test/ui/issue-32829.rs b/src/test/ui/issue-32829.rs
index 9ac70882ca2..60e83138c76 100644
--- a/src/test/ui/issue-32829.rs
+++ b/src/test/ui/issue-32829.rs
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: calls in statics are limited
-
 static S : u64 = { { panic!("foo"); 0 } };
+//~^ ERROR calls in statics are limited
 
 fn main() {
     println!("{:?}", S);
diff --git a/src/test/ui/issue-32829.stderr b/src/test/ui/issue-32829.stderr
index fc7d356411a..30b6a642904 100644
--- a/src/test/ui/issue-32829.stderr
+++ b/src/test/ui/issue-32829.stderr
@@ -1,5 +1,5 @@
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/issue-32829.rs:13:22
+  --> $DIR/issue-32829.rs:11:22
    |
 LL | static S : u64 = { { panic!("foo"); 0 } };
    |                      ^^^^^^^^^^^^^^
diff --git a/src/test/ui/issue-50577.rs b/src/test/ui/issue-50577.rs
index a3bb6872424..6fd680c1519 100644
--- a/src/test/ui/issue-50577.rs
+++ b/src/test/ui/issue-50577.rs
@@ -11,5 +11,6 @@
 fn main() {
     enum Foo {
         Drop = assert_eq!(1, 1)
+        //~^ ERROR if may be missing an else clause
     }
 }
diff --git a/src/test/ui/issue-51848.rs b/src/test/ui/issue-51848.rs
new file mode 100644
index 00000000000..ec90d3f62d2
--- /dev/null
+++ b/src/test/ui/issue-51848.rs
@@ -0,0 +1,30 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// In case of macro expansion, the errors should be matched using the deepest callsite in the
+// macro call stack whose span is in the current file
+
+macro_rules! macro_with_error {
+    ( ) => {
+        println!("{"); //~ ERROR invalid
+    };
+}
+
+fn foo() {
+
+}
+
+fn main() {
+    macro_with_error!();
+    //^ In case of a local macro we want the error to be matched in the macro definition, not here
+
+    println!("}"); //~ ERROR invalid
+    //^ In case of an external macro we want the error to be matched here
+}
diff --git a/src/test/ui/issue-51848.stderr b/src/test/ui/issue-51848.stderr
new file mode 100644
index 00000000000..8e5001dca33
--- /dev/null
+++ b/src/test/ui/issue-51848.stderr
@@ -0,0 +1,21 @@
+error: invalid format string: expected `'}'` but string was terminated
+  --> $DIR/issue-51848.rs:16:20
+   |
+LL |         println!("{"); //~ ERROR invalid
+   |                    ^ expected `'}'` in format string
+...
+LL |     macro_with_error!();
+   |     -------------------- in this macro invocation
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: unmatched `}` found
+  --> $DIR/issue-51848.rs:28:15
+   |
+LL |     println!("}"); //~ ERROR invalid
+   |               ^ unmatched `}` in format string
+   |
+   = note: if you intended to print `}`, you can escape it using `}}`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.nll.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.nll.stderr
index 7b7302ae582..a485c80f3b0 100644
--- a/src/test/ui/lifetimes/borrowck-let-suggestion.nll.stderr
+++ b/src/test/ui/lifetimes/borrowck-let-suggestion.nll.stderr
@@ -5,6 +5,7 @@ LL |     let mut x = vec![1].iter();
    |                 ^^^^^^^       - temporary value only lives until here
    |                 |
    |                 temporary value does not live long enough
+LL |     //~^ ERROR borrowed value does not live long enough
 LL |     x.use_mut();
    |     - borrow later used here
    |
diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.rs b/src/test/ui/lifetimes/borrowck-let-suggestion.rs
index 51a2a1fc883..37d6e351828 100644
--- a/src/test/ui/lifetimes/borrowck-let-suggestion.rs
+++ b/src/test/ui/lifetimes/borrowck-let-suggestion.rs
@@ -10,6 +10,7 @@
 
 fn f() {
     let mut x = vec![1].iter();
+    //~^ ERROR borrowed value does not live long enough
     x.use_mut();
 }
 
diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
index 32fdb9df96f..a7ff1fd9d0a 100644
--- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
+++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
@@ -5,7 +5,7 @@ LL |     let mut x = vec![1].iter();
    |                 ^^^^^^^       - temporary value dropped here while still borrowed
    |                 |
    |                 temporary value does not live long enough
-LL |     x.use_mut();
+...
 LL | }
    | - temporary value needs to live until here
    |
diff --git a/src/test/ui/reachable/expr_again.rs b/src/test/ui/reachable/expr_again.rs
index cdbdb8dc0db..cf6a1f7b3b4 100644
--- a/src/test/ui/reachable/expr_again.rs
+++ b/src/test/ui/reachable/expr_again.rs
@@ -16,5 +16,6 @@ fn main() {
     let x = loop {
         continue;
         println!("hi");
+        //~^ ERROR unreachable statement
     };
 }
diff --git a/src/test/ui/reachable/expr_block.rs b/src/test/ui/reachable/expr_block.rs
index 93bce43f76d..1f74f61ce2a 100644
--- a/src/test/ui/reachable/expr_block.rs
+++ b/src/test/ui/reachable/expr_block.rs
@@ -33,6 +33,7 @@ fn c() {
     let x = {
         return;
         println!("foo");
+        //~^ ERROR unreachable statement
         22
     };
 }
diff --git a/src/test/ui/reachable/expr_if.rs b/src/test/ui/reachable/expr_if.rs
index d2fb1044e48..4b540ab5b7e 100644
--- a/src/test/ui/reachable/expr_if.rs
+++ b/src/test/ui/reachable/expr_if.rs
@@ -35,6 +35,7 @@ fn baz() {
     // As the next action to be taken after the if arms, we should
     // report the `println!` as unreachable:
     println!("But I am.");
+    //~^ ERROR unreachable statement
 }
 
 fn main() { }
diff --git a/src/test/ui/reachable/expr_loop.rs b/src/test/ui/reachable/expr_loop.rs
index 533cdac0968..41394f20484 100644
--- a/src/test/ui/reachable/expr_loop.rs
+++ b/src/test/ui/reachable/expr_loop.rs
@@ -16,6 +16,7 @@
 fn a() {
     loop { return; }
     println!("I am dead.");
+    //~^ ERROR unreachable statement
 }
 
 fn b() {
@@ -28,6 +29,7 @@ fn b() {
 fn c() {
     loop { return; }
     println!("I am dead.");
+    //~^ ERROR unreachable statement
 }
 
 fn d() {
@@ -38,6 +40,7 @@ fn d() {
 fn e() {
     loop { 'middle: loop { loop { break 'middle; } } }
     println!("I am dead.");
+    //~^ ERROR unreachable statement
 }
 
 fn main() { }
diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr
index a51ef293acf..0208972a3df 100644
--- a/src/test/ui/reachable/expr_loop.stderr
+++ b/src/test/ui/reachable/expr_loop.stderr
@@ -12,7 +12,7 @@ LL | #![deny(unreachable_code)]
    = 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:30:5
+  --> $DIR/expr_loop.rs:31:5
    |
 LL |     println!("I am dead.");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL |     println!("I am dead.");
    = 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:40:5
+  --> $DIR/expr_loop.rs:42:5
    |
 LL |     println!("I am dead.");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/reachable/expr_match.rs b/src/test/ui/reachable/expr_match.rs
index 193edd77435..2faa262d110 100644
--- a/src/test/ui/reachable/expr_match.rs
+++ b/src/test/ui/reachable/expr_match.rs
@@ -22,6 +22,7 @@ fn a() {
 fn b() {
     match () { () => return }
     println!("I am dead");
+    //~^ ERROR unreachable statement
 }
 
 fn c() {
@@ -32,6 +33,7 @@ fn c() {
 fn d() {
     match () { () if false => return, () => return }
     println!("I am dead");
+    //~^ ERROR unreachable statement
 }
 
 fn e() {
diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr
index dfc1417f3d2..240341232d8 100644
--- a/src/test/ui/reachable/expr_match.stderr
+++ b/src/test/ui/reachable/expr_match.stderr
@@ -19,7 +19,7 @@ LL |     println!("I am dead");
    = 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:34:5
+  --> $DIR/expr_match.rs:35:5
    |
 LL |     println!("I am dead");
    |     ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/reachable/expr_while.rs b/src/test/ui/reachable/expr_while.rs
index 79fa69a9289..27e8d5d9b97 100644
--- a/src/test/ui/reachable/expr_while.rs
+++ b/src/test/ui/reachable/expr_while.rs
@@ -16,6 +16,7 @@
 fn foo() {
     while {return} {
         println!("Hello, world!");
+        //~^ ERROR unreachable
     }
 }
 
@@ -30,8 +31,10 @@ fn baz() {
     // Here, we cite the `while` loop as dead.
     while {return} {
         println!("I am dead.");
+        //~^ ERROR unreachable
     }
     println!("I am, too.");
+    //~^ ERROR unreachable
 }
 
 fn main() { }
diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr
index 90c35bfaa7a..3a27fe5e027 100644
--- a/src/test/ui/reachable/expr_while.stderr
+++ b/src/test/ui/reachable/expr_while.stderr
@@ -12,7 +12,7 @@ LL | #![deny(unreachable_code)]
    = 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_while.rs:32:9
+  --> $DIR/expr_while.rs:33:9
    |
 LL |         println!("I am dead.");
    |         ^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL |         println!("I am dead.");
    = 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_while.rs:34:5
+  --> $DIR/expr_while.rs:36:5
    |
 LL |     println!("I am, too.");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/span/coerce-suggestions.rs b/src/test/ui/span/coerce-suggestions.rs
index 95461ee8093..48653ba0562 100644
--- a/src/test/ui/span/coerce-suggestions.rs
+++ b/src/test/ui/span/coerce-suggestions.rs
@@ -29,4 +29,5 @@ fn main() {
 
     let s = &mut String::new();
     s = format!("foo");
+    //~^ ERROR E0308
 }
diff --git a/src/test/ui/span/issue-33884.rs b/src/test/ui/span/issue-33884.rs
index d0f23caa538..f7836a6790f 100644
--- a/src/test/ui/span/issue-33884.rs
+++ b/src/test/ui/span/issue-33884.rs
@@ -16,6 +16,7 @@ use std::io::{self, Read, Write};
 
 fn handle_client(stream: TcpStream) -> io::Result<()> {
     stream.write_fmt(format!("message received"))
+    //~^ ERROR mismatched types
 }
 
 fn main() {
diff --git a/src/test/ui/span/slice-borrow.nll.stderr b/src/test/ui/span/slice-borrow.nll.stderr
index 35838184e33..aefba8324cf 100644
--- a/src/test/ui/span/slice-borrow.nll.stderr
+++ b/src/test/ui/span/slice-borrow.nll.stderr
@@ -3,7 +3,7 @@ error[E0597]: borrowed value does not live long enough
    |
 LL |         let x: &[isize] = &vec![1, 2, 3, 4, 5];
    |                            ^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
-LL |         y = &x[1..];
+...
 LL |     }
    |     - temporary value only lives until here
 LL |     y.use_ref();
diff --git a/src/test/ui/span/slice-borrow.rs b/src/test/ui/span/slice-borrow.rs
index 2d9b49d89b8..27765fe56fd 100644
--- a/src/test/ui/span/slice-borrow.rs
+++ b/src/test/ui/span/slice-borrow.rs
@@ -14,6 +14,7 @@ fn main() {
     let y;
     {
         let x: &[isize] = &vec![1, 2, 3, 4, 5];
+        //~^ ERROR borrowed value does not live long enough
         y = &x[1..];
     }
     y.use_ref();
diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr
index cb170648891..cdcb65bf9f1 100644
--- a/src/test/ui/span/slice-borrow.stderr
+++ b/src/test/ui/span/slice-borrow.stderr
@@ -3,7 +3,7 @@ error[E0597]: borrowed value does not live long enough
    |
 LL |         let x: &[isize] = &vec![1, 2, 3, 4, 5];
    |                            ^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
-LL |         y = &x[1..];
+...
 LL |     }
    |     - temporary value dropped here while still borrowed
 LL |     y.use_ref();
diff --git a/src/test/ui/type-check/cannot_infer_local_or_vec.rs b/src/test/ui/type-check/cannot_infer_local_or_vec.rs
index a9943f75336..a4626799691 100644
--- a/src/test/ui/type-check/cannot_infer_local_or_vec.rs
+++ b/src/test/ui/type-check/cannot_infer_local_or_vec.rs
@@ -10,4 +10,5 @@
 
 fn main() {
     let x = vec![];
+    //~^ ERROR type annotations needed
 }
diff --git a/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.rs b/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.rs
index 8d32c1ff683..930c51f52d9 100644
--- a/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.rs
+++ b/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.rs
@@ -10,4 +10,5 @@
 
 fn main() {
     let (x, ) = (vec![], );
+    //~^ ERROR type annotations needed
 }
diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs
index 165f2914ae2..201a661726e 100644
--- a/src/tools/compiletest/src/json.rs
+++ b/src/tools/compiletest/src/json.rs
@@ -40,6 +40,21 @@ struct DiagnosticSpan {
     expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
 }
 
+impl DiagnosticSpan {
+    /// Returns the deepest source span in the macro call stack with a given file name.
+    /// This is either the supplied span, or the span for some macro callsite that expanded to it.
+    fn first_callsite_in_file(&self, file_name: &str) -> &DiagnosticSpan {
+        if self.file_name == file_name {
+            self
+        } else {
+            self.expansion
+                .as_ref()
+                .map(|origin| origin.span.first_callsite_in_file(file_name))
+                .unwrap_or(self)
+        }
+    }
+}
+
 #[derive(Deserialize, Clone)]
 struct DiagnosticSpanMacroExpansion {
     /// span where macro was applied to generate this code
@@ -115,16 +130,23 @@ fn push_expected_errors(
     default_spans: &[&DiagnosticSpan],
     file_name: &str,
 ) {
-    let spans_in_this_file: Vec<_> = diagnostic
+    // In case of macro expansions, we need to get the span of the callsite
+    let spans_info_in_this_file: Vec<_> = diagnostic
         .spans
         .iter()
-        .filter(|span| Path::new(&span.file_name) == Path::new(&file_name))
+        .map(|span| (span.is_primary, span.first_callsite_in_file(file_name)))
+        .filter(|(_, span)| Path::new(&span.file_name) == Path::new(&file_name))
         .collect();
 
-    let primary_spans: Vec<_> = spans_in_this_file.iter()
-        .cloned()
-        .filter(|span| span.is_primary)
+    let spans_in_this_file: Vec<_> = spans_info_in_this_file.iter()
+        .map(|(_, span)| span)
+        .collect();
+
+    let primary_spans: Vec<_> = spans_info_in_this_file.iter()
+        .filter(|(is_primary, _)| *is_primary)
+        .map(|(_, span)| span)
         .take(1) // sometimes we have more than one showing up in the json; pick first
+        .cloned()
         .collect();
     let primary_spans = if primary_spans.is_empty() {
         // subdiagnostics often don't have a span of their own;
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index fcc47436225..ad86844cec3 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1194,6 +1194,10 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("process did not return an error status", proc_res);
         }
 
+        // On Windows, keep all '\' path separators to match the paths reported in the JSON output
+        // from the compiler
+        let os_file_name = self.testpaths.file.display().to_string();
+
         // on windows, translate all '\' path separators to '/'
         let file_name = format!("{}", self.testpaths.file.display()).replace(r"\", "/");
 
@@ -1209,7 +1213,7 @@ impl<'test> TestCx<'test> {
             .any(|ee| ee.kind == Some(ErrorKind::Note));
 
         // Parse the JSON output from the compiler and extract out the messages.
-        let actual_errors = json::parse_output(&file_name, &proc_res.stderr, proc_res);
+        let actual_errors = json::parse_output(&os_file_name, &proc_res.stderr, proc_res);
         let mut unexpected = Vec::new();
         let mut found = vec![false; expected_errors.len()];
         for actual_error in &actual_errors {