Skip to content

Unsoundness and ICE due to DispatchFromDyn allowing bogus impls on references. #148727

@theemathas

Description

@theemathas

Code

#![feature(dispatch_from_dyn, arbitrary_self_types)]

use std::ops::{DispatchFromDyn, Receiver};

pub struct Ptr<T: ?Sized>(Box<T>, Box<T>);

impl<'a, T: ?Sized, U: ?Sized> DispatchFromDyn<&'a Ptr<U>> for &'a Ptr<T> {}
impl<T: ?Sized> Receiver for Ptr<T> {
    type Target = T;
}

pub trait Trait {
    fn method(self: &Ptr<Self>) {}
}

struct Thing;
impl Trait for Thing {}

fn main() {
    let x: Ptr<dyn Trait> = Ptr(
        Box::new(Thing) as Box<dyn Trait>,
        Box::new(Thing) as Box<dyn Trait>,
    );
    x.method();
}

DispatchFromDyn does some validation on impls to ensure that they're sensible. However, for some reason, it is currently documented to always allow impls on references. This leads to bogus impls such as above.

Meta

Reproducible on the playground with version 1.93.0-nightly (2025-11-08 fb23dd3c6b120f0d2e55)

Error output

error: internal compiler error: /rustc-dev/fb23dd3c6b120f0d2e55e5f2c69a464df7b35fdf/compiler/rustc_codegen_ssa/src/mir/block.rs:1148:25: can't codegen a virtual call on OperandRef(Immediate((ptr:  %3 = alloca [32 x i8], align 8)) @ TyAndLayout { ty: &Ptr<dyn Trait>, layout: Layout { size: Size(8 bytes), align: AbiAlign { abi: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } })
  --> src/main.rs:24:7
   |
24 |     x.method();
   |       ^^^^^^^^


thread 'rustc' (28) panicked at /rustc-dev/fb23dd3c6b120f0d2e55e5f2c69a464df7b35fdf/compiler/rustc_codegen_ssa/src/mir/block.rs:1148:25:
Box<dyn Any>
Backtrace

stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
   1: <rustc_errors::diagnostic::BugAbort as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
   2: <rustc_errors::DiagCtxtHandle>::span_bug::<rustc_span::span_encoding::Span, alloc::string::String>
   3: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>::{closure#0}
   4: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>::{closure#0}
   5: rustc_middle::ty::context::tls::with_context_opt::<rustc_middle::ty::context::tls::with_opt<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
   6: rustc_middle::util::bug::span_bug_fmt::<rustc_span::span_encoding::Span>
   7: rustc_codegen_ssa::mir::codegen_mir::<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
   8: rustc_codegen_llvm::base::compile_codegen_unit::module_codegen
   9: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::ExtraBackendMethods>::compile_codegen_unit
  10: rustc_codegen_ssa::base::codegen_crate::<rustc_codegen_llvm::LlvmCodegenBackend>
  11: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  12: <rustc_interface::queries::Linker>::codegen_and_build_linker
  13: <rustc_interface::passes::create_and_enter_global_ctxt<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>::{closure#2} as core::ops::function::FnOnce<(&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, alloc::sync::Arc<rustc_data_structures::jobserver::Proxy>, &std::sync::once_lock::OnceLock<rustc_middle::ty::context::GlobalCtxt>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_middle::arena::Arena>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_hir::Arena>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2})>>::call_once::{shim:vtable#0}
  14: rustc_interface::interface::run_compiler::<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: please make sure that you have updated to the latest nightly

note: please attach the file at `/playground/rustc-ice-2025-11-09T04_18_49-26.txt` to your bug report

note: compiler flags: --crate-type bin -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
end of query stack

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-dyn-compatibilityArea: Dyn compatibility (formerly: object safety)C-bugCategory: This is a bug.F-arbitrary_self_types`#![feature(arbitrary_self_types)]`F-dispatch_from_dyn`#![feature(dispatch_from_dyn)]`I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️I-lang-radarItems that are on lang's radar and will need eventual work or consideration.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions