From 4cfb7add771367757ee2dd26da4e29d333c93cb6 Mon Sep 17 00:00:00 2001
From: Cameron Steffen <cam.steffen94@gmail.com>
Date: Thu, 21 Oct 2021 09:01:16 -0500
Subject: [PATCH 1/5] Fix a format_args span to be expansion

---
 compiler/rustc_builtin_macros/src/format.rs                  | 5 ++++-
 src/test/ui/borrowck/borrowck-and-init.stderr                | 2 ++
 src/test/ui/borrowck/borrowck-break-uninit-2.stderr          | 2 ++
 src/test/ui/borrowck/borrowck-break-uninit.stderr            | 2 ++
 src/test/ui/borrowck/borrowck-or-init.stderr                 | 2 ++
 src/test/ui/borrowck/borrowck-while-break.stderr             | 2 ++
 src/test/ui/borrowck/issue-24267-flow-exit.stderr            | 4 ++++
 .../closures/2229_closure_analysis/diagnostics/arrays.stderr | 2 ++
 .../ui/closures/2229_closure_analysis/diagnostics/box.stderr | 2 ++
 .../2229_closure_analysis/diagnostics/repr_packed.stderr     | 1 +
 .../diagnostics/simple-struct-min-capture.stderr             | 2 ++
 src/test/ui/codemap_tests/tab_3.stderr                       | 1 +
 .../ui/consts/const-eval/conditional_array_execution.stderr  | 1 +
 src/test/ui/consts/const-eval/issue-43197.stderr             | 2 ++
 src/test/ui/generator/yield-while-ref-reborrowed.stderr      | 2 ++
 src/test/ui/issues/issue-42796.stderr                        | 2 ++
 src/test/ui/issues/issue-47646.stderr                        | 2 ++
 src/test/ui/limits/issue-55878.stderr                        | 1 +
 src/test/ui/liveness/liveness-move-in-while.stderr           | 2 ++
 src/test/ui/liveness/liveness-use-after-move.stderr          | 2 ++
 src/test/ui/liveness/liveness-use-after-send.stderr          | 2 ++
 src/test/ui/loops/loop-proper-liveness.stderr                | 2 ++
 .../ui/moves/moves-based-on-type-capture-clause-bad.stderr   | 2 ++
 src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr    | 2 ++
 src/test/ui/use/use-after-move-based-on-type.stderr          | 2 ++
 src/test/ui/walk-struct-literal-with.stderr                  | 1 +
 26 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index f0056cb79766..3f9ea371583b 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -793,7 +793,10 @@ impl<'a, 'b> Context<'a, 'b> {
             for arg_ty in self.arg_unique_types[i].iter() {
                 locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name));
             }
-            heads.push(self.ecx.expr_addr_of(e.span, e));
+            // use the arg span for `&arg` so that borrowck errors
+            // point to the specific expression passed to the macro
+            // (the span is otherwise unavailable in MIR)
+            heads.push(self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e));
         }
         for pos in self.count_args {
             let index = match pos {
diff --git a/src/test/ui/borrowck/borrowck-and-init.stderr b/src/test/ui/borrowck/borrowck-and-init.stderr
index c7e357d4604f..d2c7473c036b 100644
--- a/src/test/ui/borrowck/borrowck-and-init.stderr
+++ b/src/test/ui/borrowck/borrowck-and-init.stderr
@@ -3,6 +3,8 @@ error[E0381]: borrow of possibly-uninitialized variable: `i`
    |
 LL |     println!("{}", i);
    |                    ^ use of possibly-uninitialized `i`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
index bc9b25c0221f..b134f5cc2d8e 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
+++ b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
@@ -3,6 +3,8 @@ error[E0381]: borrow of possibly-uninitialized variable: `x`
    |
 LL |     println!("{}", x);
    |                    ^ use of possibly-uninitialized `x`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-break-uninit.stderr b/src/test/ui/borrowck/borrowck-break-uninit.stderr
index 766d5cfd6348..652d7d3076fb 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit.stderr
+++ b/src/test/ui/borrowck/borrowck-break-uninit.stderr
@@ -3,6 +3,8 @@ error[E0381]: borrow of possibly-uninitialized variable: `x`
    |
 LL |     println!("{}", x);
    |                    ^ use of possibly-uninitialized `x`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-or-init.stderr b/src/test/ui/borrowck/borrowck-or-init.stderr
index 3fe8d9eededc..6c757759f713 100644
--- a/src/test/ui/borrowck/borrowck-or-init.stderr
+++ b/src/test/ui/borrowck/borrowck-or-init.stderr
@@ -3,6 +3,8 @@ error[E0381]: borrow of possibly-uninitialized variable: `i`
    |
 LL |     println!("{}", i);
    |                    ^ use of possibly-uninitialized `i`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-while-break.stderr b/src/test/ui/borrowck/borrowck-while-break.stderr
index 3eaaf8d7df08..fc144a066bb2 100644
--- a/src/test/ui/borrowck/borrowck-while-break.stderr
+++ b/src/test/ui/borrowck/borrowck-while-break.stderr
@@ -3,6 +3,8 @@ error[E0381]: borrow of possibly-uninitialized variable: `v`
    |
 LL |     println!("{}", v);
    |                    ^ use of possibly-uninitialized `v`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/issue-24267-flow-exit.stderr b/src/test/ui/borrowck/issue-24267-flow-exit.stderr
index 4eb41ca24ddf..e29cf7a1a751 100644
--- a/src/test/ui/borrowck/issue-24267-flow-exit.stderr
+++ b/src/test/ui/borrowck/issue-24267-flow-exit.stderr
@@ -3,12 +3,16 @@ error[E0381]: borrow of possibly-uninitialized variable: `x`
    |
 LL |     println!("{}", x);
    |                    ^ use of possibly-uninitialized `x`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/issue-24267-flow-exit.rs:18:20
    |
 LL |     println!("{}", x);
    |                    ^ use of possibly-uninitialized `x`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
index a3f2f25e447e..f6c219018321 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
@@ -81,6 +81,8 @@ LL |     println!("{}", arr[3]);
 ...
 LL |     c();
    |     - mutable borrow later used here
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable
   --> $DIR/arrays.rs:73:24
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
index 2badf0514187..29228d85324e 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
@@ -25,6 +25,8 @@ LL |     println!("{}", e.0.0.m.x);
 LL |
 LL |     c();
    |     - mutable borrow later used here
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
   --> $DIR/box.rs:55:5
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
index d2466681a087..5acf3797ab53 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
@@ -8,6 +8,7 @@ LL |         println!("{}", foo.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 #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
index 32705af3d016..4f9fdbd368a8 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
@@ -13,6 +13,8 @@ LL |     println!("{:?}", p);
 LL |
 LL |     c();
    |     - mutable borrow later used here
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/codemap_tests/tab_3.stderr b/src/test/ui/codemap_tests/tab_3.stderr
index e067dbbf85bd..ceb91142ac82 100644
--- a/src/test/ui/codemap_tests/tab_3.stderr
+++ b/src/test/ui/codemap_tests/tab_3.stderr
@@ -14,6 +14,7 @@ note: this function takes ownership of the receiver `self`, which moves `some_ve
    |
 LL |     fn into_iter(self) -> Self::IntoIter;
    |                  ^^^^
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr
index 356a7f58d856..9dc40030a6ff 100644
--- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr
+++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr
@@ -28,6 +28,7 @@ LL |     println!("{}", FOO);
    |
    = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error; 2 warnings emitted
 
diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr
index d4d8cbc669a7..32ab7c74b891 100644
--- a/src/test/ui/consts/const-eval/issue-43197.stderr
+++ b/src/test/ui/consts/const-eval/issue-43197.stderr
@@ -39,6 +39,7 @@ LL |     println!("{} {}", X, Y);
    |
    = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/issue-43197.rs:16:26
@@ -54,6 +55,7 @@ LL |     println!("{} {}", X, Y);
    |
    = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 2 previous errors; 4 warnings emitted
 
diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.stderr
index 68d785efcfe5..67cd1f64d94a 100644
--- a/src/test/ui/generator/yield-while-ref-reborrowed.stderr
+++ b/src/test/ui/generator/yield-while-ref-reborrowed.stderr
@@ -10,6 +10,8 @@ LL |     println!("{}", x);
    |                    ^ second borrow occurs here
 LL |     Pin::new(&mut b).resume(());
    |              ------ first borrow later used here
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-42796.stderr b/src/test/ui/issues/issue-42796.stderr
index 61cf3f25d0d0..4a1debf37a07 100644
--- a/src/test/ui/issues/issue-42796.stderr
+++ b/src/test/ui/issues/issue-42796.stderr
@@ -8,6 +8,8 @@ LL |     let mut s_copy = s;
 ...
 LL |     println!("{}", s);
    |                    ^ value borrowed here after move
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-47646.stderr b/src/test/ui/issues/issue-47646.stderr
index eff1de3e0175..32e8588b3c07 100644
--- a/src/test/ui/issues/issue-47646.stderr
+++ b/src/test/ui/issues/issue-47646.stderr
@@ -12,6 +12,8 @@ LL |             println!("{:?}", heap);
 ...
 LL |     };
    |      - ... and the mutable borrow might be used here, when that temporary is dropped and runs the destructor for type `(Option<PeekMut<'_, i32>>, ())`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/limits/issue-55878.stderr b/src/test/ui/limits/issue-55878.stderr
index a7e382479021..90411353f082 100644
--- a/src/test/ui/limits/issue-55878.stderr
+++ b/src/test/ui/limits/issue-55878.stderr
@@ -18,6 +18,7 @@ LL |     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
    = note: `#[deny(const_err)]` 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/liveness/liveness-move-in-while.stderr b/src/test/ui/liveness/liveness-move-in-while.stderr
index 6a8f239bd09a..ff6c02f2110f 100644
--- a/src/test/ui/liveness/liveness-move-in-while.stderr
+++ b/src/test/ui/liveness/liveness-move-in-while.stderr
@@ -28,6 +28,8 @@ LL |         println!("{}", y);
    |                        ^ value borrowed here after move
 LL |         while true { while true { while true { x = y; x.clone(); } } }
    |                                                    - value moved here, in previous iteration of loop
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error; 3 warnings emitted
 
diff --git a/src/test/ui/liveness/liveness-use-after-move.stderr b/src/test/ui/liveness/liveness-use-after-move.stderr
index 292ce013dcc7..df54af9f0f2c 100644
--- a/src/test/ui/liveness/liveness-use-after-move.stderr
+++ b/src/test/ui/liveness/liveness-use-after-move.stderr
@@ -8,6 +8,8 @@ LL |     let y = x;
 LL | 
 LL |     println!("{}", *x);
    |                    ^^ value borrowed here after move
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/liveness/liveness-use-after-send.stderr b/src/test/ui/liveness/liveness-use-after-send.stderr
index 50ae98ca9bed..becede1ceb6b 100644
--- a/src/test/ui/liveness/liveness-use-after-send.stderr
+++ b/src/test/ui/liveness/liveness-use-after-send.stderr
@@ -7,6 +7,8 @@ LL |     send(ch, message);
    |              ------- value moved here
 LL |     println!("{}", message);
    |                    ^^^^^^^ value borrowed here after move
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/loops/loop-proper-liveness.stderr b/src/test/ui/loops/loop-proper-liveness.stderr
index d55f9ff31e3e..20d5c66a3f20 100644
--- a/src/test/ui/loops/loop-proper-liveness.stderr
+++ b/src/test/ui/loops/loop-proper-liveness.stderr
@@ -3,6 +3,8 @@ error[E0381]: borrow of possibly-uninitialized variable: `x`
    |
 LL |     println!("{:?}", x);
    |                      ^ use of possibly-uninitialized `x`
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/moves/moves-based-on-type-capture-clause-bad.stderr b/src/test/ui/moves/moves-based-on-type-capture-clause-bad.stderr
index acb0932f6d6b..ac921c18e07d 100644
--- a/src/test/ui/moves/moves-based-on-type-capture-clause-bad.stderr
+++ b/src/test/ui/moves/moves-based-on-type-capture-clause-bad.stderr
@@ -10,6 +10,8 @@ LL |         println!("{}", x);
 LL |     });
 LL |     println!("{}", x);
    |                    ^ value borrowed here after move
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr b/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr
index c092aa26946f..d6822d94ca8c 100644
--- a/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr
+++ b/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr
@@ -21,6 +21,8 @@ LL |             ::std::mem::drop(x);
 LL |         };
 LL |         println!("{}", x);
    |                        ^ value borrowed here after move
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0506]: cannot assign to `i` because it is borrowed
   --> $DIR/try-block-maybe-bad-lifetime.rs:40:9
diff --git a/src/test/ui/use/use-after-move-based-on-type.stderr b/src/test/ui/use/use-after-move-based-on-type.stderr
index 11ce005bb457..361a6e2d8c27 100644
--- a/src/test/ui/use/use-after-move-based-on-type.stderr
+++ b/src/test/ui/use/use-after-move-based-on-type.stderr
@@ -7,6 +7,8 @@ LL |     let _y = x;
    |              - value moved here
 LL |     println!("{}", x);
    |                    ^ value borrowed here after move
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/walk-struct-literal-with.stderr b/src/test/ui/walk-struct-literal-with.stderr
index cda08b0f4e09..377a80744589 100644
--- a/src/test/ui/walk-struct-literal-with.stderr
+++ b/src/test/ui/walk-struct-literal-with.stderr
@@ -13,6 +13,7 @@ note: this function takes ownership of the receiver `self`, which moves `start`
    |
 LL |     fn make_string_bar(mut self) -> Mine{
    |                            ^^^^
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 

From b16ac4cbbae108bfd184569a2c50bde247d04fdf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Fri, 12 Nov 2021 00:00:00 +0000
Subject: [PATCH 2/5] Use brief format for optimization remarks

---
 compiler/rustc_codegen_llvm/src/back/write.rs | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 3d05fc15b38f..80fc39846cd1 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -337,13 +337,8 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
 
             if enabled {
                 diag_handler.note_without_error(&format!(
-                    "optimization {} for {} at {}:{}:{}: {}",
-                    opt.kind.describe(),
-                    opt.pass_name,
-                    opt.filename,
-                    opt.line,
-                    opt.column,
-                    opt.message
+                    "{}:{}:{}: {}: {}",
+                    opt.filename, opt.line, opt.column, opt.pass_name, opt.message,
                 ));
             }
         }

From 6846674c75530796b3d7709ff8a602e046ce08d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Fri, 12 Nov 2021 00:00:00 +0000
Subject: [PATCH 3/5] Emit LLVM optimization remarks when enabled with
 `-Cremark`

The default diagnostic handler considers all remarks to be disabled by
default unless configured otherwise through LLVM internal flags:
`-pass-remarks`, `-pass-remarks-missed`, and `-pass-remarks-analysis`.
This behaviour makes `-Cremark` ineffective on its own.

Fix this by configuring a custom diagnostic handler that enables
optimization remarks based on the value of `-Cremark` option. With
`-Cremark=all` enabling all remarks.
---
 compiler/rustc_codegen_llvm/src/back/write.rs | 30 ++++++-
 compiler/rustc_codegen_llvm/src/llvm/ffi.rs   | 31 +++++--
 .../rustc_llvm/llvm-wrapper/RustWrapper.cpp   | 90 +++++++++++++++++++
 src/test/ui/optimization-remark.rs            | 19 ++++
 4 files changed, 158 insertions(+), 12 deletions(-)
 create mode 100644 src/test/ui/optimization-remark.rs

diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 80fc39846cd1..460a8cc69128 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -259,6 +259,7 @@ pub(crate) fn save_temp_bitcode(
 pub struct DiagnosticHandlers<'a> {
     data: *mut (&'a CodegenContext<LlvmCodegenBackend>, &'a Handler),
     llcx: &'a llvm::Context,
+    old_handler: Option<&'a llvm::DiagnosticHandler>,
 }
 
 impl<'a> DiagnosticHandlers<'a> {
@@ -267,12 +268,35 @@ impl<'a> DiagnosticHandlers<'a> {
         handler: &'a Handler,
         llcx: &'a llvm::Context,
     ) -> Self {
+        let remark_passes_all: bool;
+        let remark_passes: Vec<CString>;
+        match &cgcx.remark {
+            Passes::All => {
+                remark_passes_all = true;
+                remark_passes = Vec::new();
+            }
+            Passes::Some(passes) => {
+                remark_passes_all = false;
+                remark_passes =
+                    passes.iter().map(|name| CString::new(name.as_str()).unwrap()).collect();
+            }
+        };
+        let remark_passes: Vec<*const c_char> =
+            remark_passes.iter().map(|name: &CString| name.as_ptr()).collect();
         let data = Box::into_raw(Box::new((cgcx, handler)));
         unsafe {
+            let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx);
+            llvm::LLVMRustContextConfigureDiagnosticHandler(
+                llcx,
+                diagnostic_handler,
+                data.cast(),
+                remark_passes_all,
+                remark_passes.as_ptr(),
+                remark_passes.len(),
+            );
             llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data.cast());
-            llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, data.cast());
+            DiagnosticHandlers { data, llcx, old_handler }
         }
-        DiagnosticHandlers { data, llcx }
     }
 }
 
@@ -281,7 +305,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
         use std::ptr::null_mut;
         unsafe {
             llvm::LLVMRustSetInlineAsmDiagnosticHandler(self.llcx, inline_asm_handler, null_mut());
-            llvm::LLVMContextSetDiagnosticHandler(self.llcx, diagnostic_handler, null_mut());
+            llvm::LLVMRustContextSetDiagnosticHandler(self.llcx, self.old_handler);
             drop(Box::from_raw(self.data));
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 749eec459aca..9bff020e5d70 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -672,8 +672,12 @@ pub struct OperandBundleDef<'a>(InvariantOpaque<'a>);
 #[repr(C)]
 pub struct Linker<'a>(InvariantOpaque<'a>);
 
-pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void);
-pub type InlineAsmDiagHandler = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint);
+extern "C" {
+    pub type DiagnosticHandler;
+}
+
+pub type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void);
+pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint);
 
 pub mod coverageinfo {
     use super::coverage_map;
@@ -2286,12 +2290,6 @@ extern "C" {
     #[allow(improper_ctypes)]
     pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString);
 
-    pub fn LLVMContextSetDiagnosticHandler(
-        C: &Context,
-        Handler: DiagnosticHandler,
-        DiagnosticContext: *mut c_void,
-    );
-
     #[allow(improper_ctypes)]
     pub fn LLVMRustUnpackOptimizationDiagnostic(
         DI: &'a DiagnosticInfo,
@@ -2321,7 +2319,7 @@ extern "C" {
 
     pub fn LLVMRustSetInlineAsmDiagnosticHandler(
         C: &Context,
-        H: InlineAsmDiagHandler,
+        H: InlineAsmDiagHandlerTy,
         CX: *mut c_void,
     );
 
@@ -2436,4 +2434,19 @@ extern "C" {
         mod_id: *const c_char,
         data: &ThinLTOData,
     );
+
+    pub fn LLVMRustContextGetDiagnosticHandler(Context: &Context) -> Option<&DiagnosticHandler>;
+    pub fn LLVMRustContextSetDiagnosticHandler(
+        context: &Context,
+        diagnostic_handler: Option<&DiagnosticHandler>,
+    );
+    pub fn LLVMRustContextConfigureDiagnosticHandler(
+        context: &Context,
+        diagnostic_handler_callback: DiagnosticHandlerTy,
+        diagnostic_handler_context: *mut c_void,
+        remark_all_passes: bool,
+        remark_passes: *const *const c_char,
+        remark_passes_len: usize,
+    );
+
 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index e77d29bed712..e8b490fb019a 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1,5 +1,6 @@
 #include "LLVMWrapper.h"
 #include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DiagnosticHandler.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/GlobalVariable.h"
@@ -1767,3 +1768,92 @@ extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
     return LLVMRustResult::Success;
   }
 }
+
+// Transfers ownership of DiagnosticHandler unique_ptr to the caller.
+extern "C" DiagnosticHandler *
+LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) {
+  std::unique_ptr<DiagnosticHandler> DH = unwrap(C)->getDiagnosticHandler();
+  return DH.release();
+}
+
+// Sets unique_ptr to object of DiagnosticHandler to provide custom diagnostic
+// handling. Ownership of the handler is moved to the LLVMContext.
+extern "C" void LLVMRustContextSetDiagnosticHandler(LLVMContextRef C,
+                                                    DiagnosticHandler *DH) {
+  unwrap(C)->setDiagnosticHandler(std::unique_ptr<DiagnosticHandler>(DH));
+}
+
+using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy;
+
+// Configures a diagnostic handler that invokes provided callback when a
+// backend needs to emit a diagnostic.
+//
+// When RemarkAllPasses is true, remarks are enabled for all passes. Otherwise
+// the RemarkPasses array specifies individual passes for which remarks will be
+// enabled.
+extern "C" void LLVMRustContextConfigureDiagnosticHandler(
+    LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
+    void *DiagnosticHandlerContext, bool RemarkAllPasses,
+    const char * const * RemarkPasses, size_t RemarkPassesLen) {
+
+  class RustDiagnosticHandler final : public DiagnosticHandler {
+  public:
+    RustDiagnosticHandler(LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
+                          void *DiagnosticHandlerContext,
+                          bool RemarkAllPasses,
+                          std::vector<std::string> RemarkPasses)
+        : DiagnosticHandlerCallback(DiagnosticHandlerCallback),
+          DiagnosticHandlerContext(DiagnosticHandlerContext),
+          RemarkAllPasses(RemarkAllPasses),
+          RemarkPasses(RemarkPasses) {}
+
+    virtual bool handleDiagnostics(const DiagnosticInfo &DI) override {
+      if (DiagnosticHandlerCallback) {
+        DiagnosticHandlerCallback(DI, DiagnosticHandlerContext);
+        return true;
+      }
+      return false;
+    }
+
+    bool isAnalysisRemarkEnabled(StringRef PassName) const override {
+      return isRemarkEnabled(PassName);
+    }
+
+    bool isMissedOptRemarkEnabled(StringRef PassName) const override {
+      return isRemarkEnabled(PassName);
+    }
+
+    bool isPassedOptRemarkEnabled(StringRef PassName) const override {
+      return isRemarkEnabled(PassName);
+    }
+
+    bool isAnyRemarkEnabled() const override {
+      return RemarkAllPasses || !RemarkPasses.empty();
+    }
+
+  private:
+    bool isRemarkEnabled(StringRef PassName) const {
+      if (RemarkAllPasses)
+        return true;
+
+      for (auto &Pass : RemarkPasses)
+        if (Pass == PassName)
+          return true;
+
+      return false;
+    }
+
+    LLVMDiagnosticHandlerTy DiagnosticHandlerCallback = nullptr;
+    void *DiagnosticHandlerContext = nullptr;
+
+    bool RemarkAllPasses = false;
+    std::vector<std::string> RemarkPasses;
+  };
+
+  std::vector<std::string> Passes;
+  for (size_t I = 0; I != RemarkPassesLen; ++I)
+    Passes.push_back(RemarkPasses[I]);
+
+  unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>(
+      DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes));
+}
diff --git a/src/test/ui/optimization-remark.rs b/src/test/ui/optimization-remark.rs
new file mode 100644
index 000000000000..7aedb09928b6
--- /dev/null
+++ b/src/test/ui/optimization-remark.rs
@@ -0,0 +1,19 @@
+// build-pass
+// ignore-pass
+// no-system-llvm
+// revisions: all inline
+//          compile-flags: --crate-type=lib -Cdebuginfo=1 -Copt-level=2
+// [all]    compile-flags: -Cremark=all
+// [inline] compile-flags: -Cremark=inline
+// error-pattern: inline: f not inlined into g
+// dont-check-compiler-stderr
+
+#[no_mangle]
+#[inline(never)]
+pub fn f() {
+}
+
+#[no_mangle]
+pub fn g() {
+    f();
+}

From 8fa45295f44febfa7035caeb149b2adfaa58fc50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Fri, 12 Nov 2021 00:00:00 +0000
Subject: [PATCH 4/5] Recognize machine optimization remarks

---
 compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index e8b490fb019a..f4b41de12e60 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1162,10 +1162,13 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
   case DK_SampleProfile:
     return LLVMRustDiagnosticKind::SampleProfile;
   case DK_OptimizationRemark:
+  case DK_MachineOptimizationRemark:
     return LLVMRustDiagnosticKind::OptimizationRemark;
   case DK_OptimizationRemarkMissed:
+  case DK_MachineOptimizationRemarkMissed:
     return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
   case DK_OptimizationRemarkAnalysis:
+  case DK_MachineOptimizationRemarkAnalysis:
     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
   case DK_OptimizationRemarkAnalysisFPCommute:
     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;

From 4c3699f01a3d1cb51e5cd1c0e913a3739adc4fc9 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Fri, 12 Nov 2021 08:17:57 -0800
Subject: [PATCH 5/5] Add 1.57.0 release notes

---
 RELEASES.md | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/RELEASES.md b/RELEASES.md
index a38ab7cabf46..4b9b20f4cba6 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,117 @@
+Version 1.57.0 (2021-12-02)
+==========================
+
+Language
+--------
+
+- [Macro attributes may follow `#[derive]` and will see the original (pre-`cfg`) input.][87220]
+- [Accept curly-brace macros in expressions, like `m!{ .. }.method()` and `m!{ .. }?`.][88690]
+- [Allow panicking in constant evaluation.][89508]
+
+Compiler
+--------
+
+- [Create more accurate debuginfo for vtables.][89597]
+- [Add `armv6k-nintendo-3ds` at Tier 3\*.][88529]
+- [Add `armv7-unknown-linux-uclibceabihf` at Tier 3\*.][88952]
+- [Add `m68k-unknown-linux-gnu` at Tier 3\*.][88321]
+- [Add SOLID targets at Tier 3\*:][86191] `aarch64-kmc-solid_asp3`, `armv7a-kmc-solid_asp3-eabi`, `armv7a-kmc-solid_asp3-eabihf`
+
+\* Refer to Rust's [platform support page][platform-support-doc] for more
+   information on Rust's tiered platform support.
+
+Libraries
+---------
+
+- [Avoid allocations and copying in `Vec::leak`][89337]
+- [Add `#[repr(i8)]` to `Ordering`][89507]
+- [Optimize `File::read_to_end` and `read_to_string`][89582]
+- [Update to Unicode 14.0][89614]
+- [Many more functions are marked `#[must_use]`][89692], producing a warning
+  when ignoring their return value. This helps catch mistakes such as expecting
+  a function to mutate a value in place rather than return a new value.
+
+Stabilised APIs
+---------------
+
+- [`[T; N]::as_mut_slice`][`array::as_mut_slice`]
+- [`[T; N]::as_slice`][`array::as_slice`]
+- [`collections::TryReserveError`]
+- [`HashMap::try_reserve`]
+- [`HashSet::try_reserve`]
+- [`String::try_reserve`]
+- [`String::try_reserve_exact`]
+- [`Vec::try_reserve`]
+- [`Vec::try_reserve_exact`]
+- [`VecDeque::try_reserve`]
+- [`VecDeque::try_reserve_exact`]
+- [`Iterator::map_while`]
+- [`iter::MapWhile`]
+- [`proc_macro::is_available`]
+- [`Command::get_program`]
+- [`Command::get_args`]
+- [`Command::get_envs`]
+- [`Command::get_current_dir`]
+- [`CommandArgs`]
+- [`CommandEnvs`]
+
+These APIs are now usable in const contexts:
+
+- [`hint::unreachable_unchecked`]
+
+Cargo
+-----
+
+- [Stabilize custom profiles][cargo/9943]
+
+Compatibility notes
+-------------------
+
+Internal changes
+----------------
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of rustc
+and related tools.
+
+- [Added an experimental backend for codegen with `libgccjit`.][87260]
+
+[86191]: https://github.com/rust-lang/rust/pull/86191/
+[87220]: https://github.com/rust-lang/rust/pull/87220/
+[87260]: https://github.com/rust-lang/rust/pull/87260/
+[88243]: https://github.com/rust-lang/rust/pull/88243/
+[88321]: https://github.com/rust-lang/rust/pull/88321/
+[88529]: https://github.com/rust-lang/rust/pull/88529/
+[88690]: https://github.com/rust-lang/rust/pull/88690/
+[88952]: https://github.com/rust-lang/rust/pull/88952/
+[89337]: https://github.com/rust-lang/rust/pull/89337/
+[89507]: https://github.com/rust-lang/rust/pull/89507/
+[89508]: https://github.com/rust-lang/rust/pull/89508/
+[89582]: https://github.com/rust-lang/rust/pull/89582/
+[89597]: https://github.com/rust-lang/rust/pull/89597/
+[89614]: https://github.com/rust-lang/rust/pull/89614/
+[89692]: https://github.com/rust-lang/rust/issues/89692/
+[cargo/9943]: https://github.com/rust-lang/cargo/pull/9943/
+[`array::as_mut_slice`]: https://doc.rust-lang.org/std/primitive.array.html#method.as_mut_slice
+[`array::as_slice`]: https://doc.rust-lang.org/std/primitive.array.html#method.as_slice
+[`collections::TryReserveError`]: https://doc.rust-lang.org/std/collections/struct.TryReserveError.html
+[`HashMap::try_reserve`]: https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.try_reserve
+[`HashSet::try_reserve`]: https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.try_reserve
+[`String::try_reserve`]: https://doc.rust-lang.org/alloc/string/struct.String.html#method.try_reserve
+[`String::try_reserve_exact`]: https://doc.rust-lang.org/alloc/string/struct.String.html#method.try_reserve_exact
+[`Vec::try_reserve`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.try_reserve
+[`Vec::try_reserve_exact`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.try_reserve_exact
+[`VecDeque::try_reserve`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.try_reserve
+[`VecDeque::try_reserve_exact`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.try_reserve_exact
+[`Iterator::map_while`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map_while
+[`iter::MapWhile`]: https://doc.rust-lang.org/std/iter/struct.MapWhile.html
+[`proc_macro::is_available`]: https://doc.rust-lang.org/proc_macro/fn.is_available.html
+[`Command::get_program`]: https://doc.rust-lang.org/std/process/struct.Command.html#method.get_program
+[`Command::get_args`]: https://doc.rust-lang.org/std/process/struct.Command.html#method.get_args
+[`Command::get_envs`]: https://doc.rust-lang.org/std/process/struct.Command.html#method.get_envs
+[`Command::get_current_dir`]: https://doc.rust-lang.org/std/process/struct.Command.html#method.get_current_dir
+[`CommandArgs`]: https://doc.rust-lang.org/std/process/struct.CommandArgs.html
+[`CommandEnvs`]: https://doc.rust-lang.org/std/process/struct.CommandEnvs.html
+
 Version 1.56.1 (2021-11-01)
 ===========================