diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index ceb044c102f69..f950594c2e03d 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1792,6 +1792,13 @@ fn create_mono_items_for_default_impls<'tcx>( let args = trait_ref.args.extend_to(tcx, method.def_id, only_region_params); let instance = ty::Instance::expect_resolve(tcx, typing_env, method.def_id, args, DUMMY_SP); + // A provided method of an `impl Trait for dyn Trait` (written via a type alias or + // projection that normalizes to the trait object) resolves to a virtual dispatch, which + // has no MIR body. Skip it rather than ICE in `instance_mir`. See #158411. + if matches!(instance.def, ty::InstanceKind::Virtual(..)) { + continue; + } + let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); if mono_item.node.is_instantiable(tcx) && tcx.should_codegen_locally(instance) { output.push(mono_item); diff --git a/tests/crashes/114198-2.rs b/tests/crashes/114198-2.rs deleted file mode 100644 index 56cb7d76e02d3..0000000000000 --- a/tests/crashes/114198-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #114198 -//@ compile-flags: -Zprint-mono-items -Clink-dead-code - -impl Trait for ::Struct {} -trait Trait { - fn test(&self) {} -} - -enum Ty {} -trait Owner { type Struct: ?Sized; } -impl Owner for Ty { - type Struct = dyn Trait + Send; -} - -fn main() {} diff --git a/tests/crashes/114198.rs b/tests/crashes/114198.rs deleted file mode 100644 index 0f479b3615fb0..0000000000000 --- a/tests/crashes/114198.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #114198 -//@ compile-flags: -Zprint-mono-items -Clink-dead-code - -#![feature(lazy_type_alias)] - -impl Trait for Struct {} -trait Trait { - fn test(&self) {} -} - -type Struct = dyn Trait + Send; - -fn main() {} diff --git a/tests/ui/codegen/mono-item-collector-dyn-self-default-impl.rs b/tests/ui/codegen/mono-item-collector-dyn-self-default-impl.rs new file mode 100644 index 0000000000000..3b5df89b51bcb --- /dev/null +++ b/tests/ui/codegen/mono-item-collector-dyn-self-default-impl.rs @@ -0,0 +1,66 @@ +// Under eager mono item collection (`-Clink-dead-code`), collecting the provided method of a trait +// implemented for (a type that normalizes to) its own trait object type used to resolve the method +// to a virtual dispatch, which has no MIR body, and crashed the collector with "virtual dispatches +// have no instance MIR". Such impls are accepted by coherence, so the program should compile. +// +// Regression test for #158411 and #114198 (an earlier report of the same bug). + +//@ build-pass +//@ compile-flags: -Clink-dead-code + +#![feature(lazy_type_alias)] +#![allow(incomplete_features)] + +// (1) Self type is a lazy type alias resolving to `dyn Trait` (the original #158411 repro). +pub trait Trait { + fn a(&self) {} +} +pub type Alias = dyn Trait; +impl Trait for Alias {} + +// (2) Self type is an associated type projection resolving to `dyn Bar`. This collects a *provided* +// method through a projection self type (the #141119 test only exercises a required method). +pub trait Bar { + fn b(&self) {} +} +pub trait Mirror { + type Assoc: ?Sized; +} +impl Mirror for T { + type Assoc = T; +} +impl Bar for ::Assoc {} + +// (3) Multiple provided methods with one overridden: `one` is a concrete `Item` and must still be +// collected, while the inherited `two` resolves to a (skipped) virtual dispatch. +pub trait Baz { + fn one(&self) {} + fn two(&self) {} +} +pub type BazAlias = dyn Baz; +impl Baz for BazAlias { + fn one(&self) {} +} + +// (4) Auto-trait component in the trait object type. +pub trait Qux { + fn q(&self) {} +} +pub type QuxAlias = dyn Qux + Send; +impl Qux for QuxAlias {} + +// (5) The self type is an associated type projection on a concrete type, so it looks non-`dyn` +// until normalized (here to `dyn Corge + Send`). This form needs no feature gate. From #114198. +pub trait Corge { + fn c(&self) {} +} +enum Ty {} +trait Owner { + type Struct: ?Sized; +} +impl Owner for Ty { + type Struct = dyn Corge + Send; +} +impl Corge for ::Struct {} + +fn main() {}