From 91f422dfda98b17688986cca817dbff9a4f8b9cb Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Sat, 30 Apr 2022 09:04:15 +0000
Subject: [PATCH] Also report the call site of PME errors locally.

Note this does not produce a full stack all the way to the first call that specifies all monomorphic parameters, it's just shallowly mentioning the last call site.
---
 compiler/rustc_monomorphize/src/collector.rs  | 10 +++---
 .../ui/consts/const-eval/issue-50814-2.stderr |  6 ++++
 .../ui/consts/const-eval/issue-50814.stderr   |  6 ++++
 .../post_monomorphization_error_backtrace.rs  | 33 +++++++++++++++++++
 ...st_monomorphization_error_backtrace.stderr | 31 +++++++++++++++++
 .../ui/polymorphization/generators.stderr     | 12 +++++++
 .../ui/polymorphization/predicates.stderr     |  6 ++++
 7 files changed, 98 insertions(+), 6 deletions(-)
 create mode 100644 src/test/ui/generics/post_monomorphization_error_backtrace.rs
 create mode 100644 src/test/ui/generics/post_monomorphization_error_backtrace.stderr

diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 0e0a4fbc21556..1828aecb375c4 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -182,7 +182,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_middle::mir::interpret::{AllocId, ConstValue};
@@ -393,6 +393,7 @@ fn collect_items_rec<'tcx>(
     // error count. If it has changed, a PME occurred, and we trigger some diagnostics about the
     // current step of mono items collection.
     //
+    // FIXME: don't rely on global state, instead bubble up errors. Note: this is very hard to do.
     let error_count = tcx.sess.diagnostic().err_count();
 
     match starting_point.node {
@@ -473,12 +474,9 @@ fn collect_items_rec<'tcx>(
     }
 
     // Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the
-    // mono item graph where the PME diagnostics are currently the most problematic (e.g. ones
-    // involving a dependency, and the lack of context is confusing) in this MVP, we focus on
-    // diagnostics on edges crossing a crate boundary: the collected mono items which are not
-    // defined in the local crate.
+    // mono item graph.
     if tcx.sess.diagnostic().err_count() > error_count
-        && starting_point.node.krate() != LOCAL_CRATE
+        && starting_point.node.is_generic_fn()
         && starting_point.node.is_user_defined()
     {
         let formatted_item = with_no_trimmed_paths!(starting_point.node.to_string());
diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr
index d34ac773da25e..298f0a4a446dd 100644
--- a/src/test/ui/consts/const-eval/issue-50814-2.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr
@@ -16,6 +16,12 @@ error[E0080]: evaluation of `foo::<()>` failed
 LL |     &<A<T> as Foo<T>>::BAR
    |      ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
 
+note: the above error was encountered while instantiating `fn foo::<()>`
+  --> $DIR/issue-50814-2.rs:31:22
+   |
+LL |     println!("{:x}", foo::<()>() as *const usize as usize);
+   |                      ^^^^^^^^^^^
+
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr
index dd8d6bf839a04..87bea28e76325 100644
--- a/src/test/ui/consts/const-eval/issue-50814.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814.stderr
@@ -16,6 +16,12 @@ error[E0080]: evaluation of `foo::<i32>` failed
 LL |     &Sum::<U8,U8>::MAX
    |      ^^^^^^^^^^^^^^^^^ referenced constant has errors
 
+note: the above error was encountered while instantiating `fn foo::<i32>`
+  --> $DIR/issue-50814.rs:26:5
+   |
+LL |     foo(0);
+   |     ^^^^^^
+
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/generics/post_monomorphization_error_backtrace.rs b/src/test/ui/generics/post_monomorphization_error_backtrace.rs
new file mode 100644
index 0000000000000..1fd9b6b3b9dba
--- /dev/null
+++ b/src/test/ui/generics/post_monomorphization_error_backtrace.rs
@@ -0,0 +1,33 @@
+// build-fail
+
+fn assert_zst<T>() {
+    struct F<T>(T);
+    impl<T> F<T> {
+        const V: () = assert!(std::mem::size_of::<T>() == 0);
+        //~^ ERROR: evaluation of `assert_zst::F::<u32>::V` failed [E0080]
+        //~| NOTE: in this expansion of assert!
+        //~| NOTE: the evaluated program panicked
+        //~| ERROR: evaluation of `assert_zst::F::<i32>::V` failed [E0080]
+        //~| NOTE: in this expansion of assert!
+        //~| NOTE: the evaluated program panicked
+    }
+    let _ = F::<T>::V;
+}
+
+fn foo<U>() {
+    assert_zst::<U>()
+    //~^ NOTE: the above error was encountered while instantiating `fn assert_zst::<u32>`
+    //~| NOTE: the above error was encountered while instantiating `fn assert_zst::<i32>`
+}
+
+
+fn bar<V>() {
+    foo::<V>()
+}
+
+fn main() {
+    bar::<()>();
+    bar::<u32>();
+    bar::<u32>();
+    bar::<i32>();
+}
diff --git a/src/test/ui/generics/post_monomorphization_error_backtrace.stderr b/src/test/ui/generics/post_monomorphization_error_backtrace.stderr
new file mode 100644
index 0000000000000..0d707d83d2660
--- /dev/null
+++ b/src/test/ui/generics/post_monomorphization_error_backtrace.stderr
@@ -0,0 +1,31 @@
+error[E0080]: evaluation of `assert_zst::F::<u32>::V` failed
+  --> $DIR/post_monomorphization_error_backtrace.rs:6:23
+   |
+LL |         const V: () = assert!(std::mem::size_of::<T>() == 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::<T>() == 0', $DIR/post_monomorphization_error_backtrace.rs:6:23
+   |
+   = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: the above error was encountered while instantiating `fn assert_zst::<u32>`
+  --> $DIR/post_monomorphization_error_backtrace.rs:18:5
+   |
+LL |     assert_zst::<U>()
+   |     ^^^^^^^^^^^^^^^^^
+
+error[E0080]: evaluation of `assert_zst::F::<i32>::V` failed
+  --> $DIR/post_monomorphization_error_backtrace.rs:6:23
+   |
+LL |         const V: () = assert!(std::mem::size_of::<T>() == 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::<T>() == 0', $DIR/post_monomorphization_error_backtrace.rs:6:23
+   |
+   = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: the above error was encountered while instantiating `fn assert_zst::<i32>`
+  --> $DIR/post_monomorphization_error_backtrace.rs:18:5
+   |
+LL |     assert_zst::<U>()
+   |     ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/polymorphization/generators.stderr b/src/test/ui/polymorphization/generators.stderr
index 9cabb21e784ad..5edbb119f7869 100644
--- a/src/test/ui/polymorphization/generators.stderr
+++ b/src/test/ui/polymorphization/generators.stderr
@@ -19,6 +19,12 @@ LL | |         2
 LL | |     }
    | |_____^
 
+note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:35:5: 39:6], u32, u32>`
+  --> $DIR/generators.rs:86:5
+   |
+LL |     finish(unused_type::<u32>());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: item has unused generic parameters
   --> $DIR/generators.rs:60:5
    |
@@ -31,5 +37,11 @@ LL | |         2
 LL | |     }
    | |_____^
 
+note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:60:5: 64:6], u32, u32>`
+  --> $DIR/generators.rs:89:5
+   |
+LL |     finish(unused_const::<1u32>());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/polymorphization/predicates.stderr b/src/test/ui/polymorphization/predicates.stderr
index 5fc51e58d728a..dc6ebceae2197 100644
--- a/src/test/ui/polymorphization/predicates.stderr
+++ b/src/test/ui/polymorphization/predicates.stderr
@@ -41,5 +41,11 @@ error: item has unused generic parameters
 LL | fn bar<I>() {
    |    ^^^ - generic parameter `I` is unused
 
+note: the above error was encountered while instantiating `fn foo::<std::slice::Iter<u32>, T>`
+  --> $DIR/predicates.rs:85:5
+   |
+LL |     foo(x.iter());
+   |     ^^^^^^^^^^^^^
+
 error: aborting due to 6 previous errors