diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f529944acce63..aff27e5664b75 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 0000000000000..1ea32ed2c4fac --- /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> {}