Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/rustc_monomorphize/src/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
15 changes: 0 additions & 15 deletions tests/crashes/114198-2.rs

This file was deleted.

13 changes: 0 additions & 13 deletions tests/crashes/114198.rs

This file was deleted.

66 changes: 66 additions & 0 deletions tests/ui/codegen/mono-item-collector-dyn-self-default-impl.rs
Original file line number Diff line number Diff line change
@@ -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<T: ?Sized> Mirror for T {
type Assoc = T;
}
impl Bar for <dyn Bar as Mirror>::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 <Ty as Owner>::Struct {}

fn main() {}
Loading