about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-03-14 01:08:48 +0000
committerMichael Goulet <michael@errs.io>2023-03-14 16:19:57 +0000
commitb36bbb0266a12f4869668f55aeaf4c8a68aa8265 (patch)
treeecef360f7954bd864db93c863259c1ed47011110
parentf1b1ed7e18f1fbe5226a96626827c625985f8285 (diff)
downloadrust-b36bbb0266a12f4869668f55aeaf4c8a68aa8265.tar.gz
rust-b36bbb0266a12f4869668f55aeaf4c8a68aa8265.zip
Don't codegen impossible to satisfy impls
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs15
-rw-r--r--tests/ui/codegen/mono-impossible.rs13
2 files changed, 28 insertions, 0 deletions
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index f529944acce..aff27e5664b 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1326,6 +1326,21 @@ fn create_mono_items_for_default_impls<'tcx>(
         return;
     }
 
+    // Unlike 'lazy' monomorphization that begins by collecting items transitively
+    // called by `main` or other global items, when eagerly monomorphizing impl
+    // items, we never actually check that the predicates of this impl are satisfied
+    // in a empty reveal-all param env (i.e. with no assumptions).
+    //
+    // Even though this impl has no substitutions, because we don't consider higher-
+    // ranked predicates such as `for<'a> &'a mut [u8]: Copy` to be trivially false,
+    // we must now check that the impl has no impossible-to-satisfy predicates.
+    if tcx.subst_and_check_impossible_predicates((
+        item.owner_id.to_def_id(),
+        &InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id()),
+    )) {
+        return;
+    }
+
     let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) else {
         return;
     };
diff --git a/tests/ui/codegen/mono-impossible.rs b/tests/ui/codegen/mono-impossible.rs
new file mode 100644
index 00000000000..1ea32ed2c4f
--- /dev/null
+++ b/tests/ui/codegen/mono-impossible.rs
@@ -0,0 +1,13 @@
+// compile-flags: -Clink-dead-code=on --crate-type=lib
+// build-pass
+
+// Make sure that we don't monomorphize the impossible method `<() as Visit>::visit`,
+// which does not hold under a reveal-all param env.
+
+pub trait Visit {
+    fn visit() {}
+}
+
+pub trait Array<'a> {}
+
+impl Visit for () where (): for<'a> Array<'a> {}