Skip to content

Conversation

@dingxiangfei2009
Copy link
Contributor

@dingxiangfei2009 dingxiangfei2009 commented Nov 18, 2025

The new checks are we check the pair of constituent types for same shapes structurally, and demand capability for dispatch for ADTs as usual; and we demand source generic parameter to be unsized of another for sanity.

Fix #148727

cc @theemathas

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Nov 18, 2025
@rustbot
Copy link
Collaborator

rustbot commented Nov 18, 2025

r? @WaffleLapkin

rustbot has assigned @WaffleLapkin.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot

This comment has been minimized.

@dingxiangfei2009
Copy link
Contributor Author

dingxiangfei2009 commented Nov 18, 2025

@theemathas What do you think? Can we break DispatchFromDyn further?

@dingxiangfei2009 dingxiangfei2009 force-pushed the dispatch-from-dyn-due-diligence branch from 75de383 to 88de0f9 Compare November 18, 2025 21:39
@rustbot

This comment has been minimized.

@dingxiangfei2009 dingxiangfei2009 force-pushed the dispatch-from-dyn-due-diligence branch from 88de0f9 to b7f84d2 Compare November 18, 2025 21:40
@theemathas
Copy link
Contributor

theemathas commented Nov 19, 2025

This code causes an ICE with this PR:

#![feature(dispatch_from_dyn, unsize, arbitrary_self_types)]

use std::{
    marker::{PhantomData, Unsize},
    ops::{DispatchFromDyn, Receiver},
};

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

impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a Ptr<U>> for &'a Ptr<T> {}

impl<T: ?Sized> Receiver for Ptr<T> {
    type Target = T;
}

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

struct Thing;
impl Trait for Thing {}

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

The compiler is probably attempting to do an dyn dispatch through two pointers, which is not possible

Error output
error: internal compiler error: /Users/timch/rust/compiler/rustc_codegen_ssa/src/mir/block.rs:1148:25: can't codegen a virtual call on OperandRef(Immediate((ptr:  %1 = alloca [16 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:25:7
   |
25 |     x.method();
   |       ^^^^^^^^


thread 'rustc' (159838) panicked at /Users/timch/rust/compiler/rustc_codegen_ssa/src/mir/block.rs:1148:25:
Box<dyn Any>
stack backtrace:
   0: begin_panic<rustc_errors::ExplicitBug>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/panicking.rs:770:5
   1: panic_any<rustc_errors::ExplicitBug>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/panic.rs:260:5
   2: emit_producing_guarantee
             at /Users/timch/rust/compiler/rustc_errors/src/diagnostic.rs:63:9
   3: emit<rustc_errors::diagnostic::BugAbort>
             at /Users/timch/rust/compiler/rustc_errors/src/diagnostic.rs:1405:9
   4: span_bug<rustc_span::span_encoding::Span, alloc::string::String>
             at /Users/timch/rust/compiler/rustc_errors/src/lib.rs:1262:48
   5: {closure#0}<rustc_span::span_encoding::Span>
             at /Users/timch/rust/compiler/rustc_middle/src/util/bug.rs:38:54
   6: {closure#0}<rustc_middle::util::bug::opt_span_bug_fmt::{closure_env#0}<rustc_span::span_encoding::Span>, !>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:136:23
   7: with_context_opt<rustc_middle::ty::context::tls::with_opt::{closure_env#0}<rustc_middle::util::bug::opt_span_bug_fmt::{closure_env#0}<rustc_span::span_encoding::Span>, !>, !>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:79:18
   8: with_opt<rustc_middle::util::bug::opt_span_bug_fmt::{closure_env#0}<rustc_span::span_encoding::Span>, !>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:134:5
   9: opt_span_bug_fmt<rustc_span::span_encoding::Span>
             at /Users/timch/rust/compiler/rustc_middle/src/util/bug.rs:33:5
  10: span_bug_fmt<rustc_span::span_encoding::Span>
             at /Users/timch/rust/compiler/rustc_middle/src/util/bug.rs:24:5
  11: codegen_call_terminator<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
  12: codegen_terminator<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
  13: codegen_block<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
             at /Users/timch/rust/compiler/rustc_codegen_ssa/src/mir/block.rs:1338:37
  14: codegen_mir<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
             at /Users/timch/rust/compiler/rustc_codegen_ssa/src/mir/mod.rs:309:12
  15: codegen_instance<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
             at /Users/timch/rust/compiler/rustc_codegen_ssa/src/base.rs:397:5
  16: define<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
             at /Users/timch/rust/compiler/rustc_codegen_ssa/src/mono_item.rs:49:21
  17: module_codegen
             at /Users/timch/rust/compiler/rustc_codegen_llvm/src/base.rs:100:27
  18: {closure#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:338:64
  19: {closure#0}<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:60:9
  20: try_with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/thread/local.rs:508:12
  21: with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/thread/local.rs:472:20
  22: enter_context<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:57:9
  23: {closure#0}<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_middle/src/dep_graph/mod.rs:36:13
  24: {closure#0}<rustc_middle::dep_graph::{impl#0}::with_deps::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:90:36
  25: with_context_opt<rustc_middle::ty::context::tls::with_context::{closure_env#0}<rustc_middle::dep_graph::{impl#0}::with_deps::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:79:18
  26: with_context<rustc_middle::dep_graph::{impl#0}::with_deps::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:90:5
  27: with_deps<rustc_query_system::dep_graph::graph::{impl#3}::with_task::{closure#1}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_middle/src/dep_graph/mod.rs:33:9
  28: {closure#1}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:338:37
  29: with_task<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:347:14
  30: with_task<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /Users/timch/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:263:32
  31: compile_codegen_unit
             at /Users/timch/rust/compiler/rustc_codegen_llvm/src/base.rs:64:37
  32: codegen_crate<rustc_codegen_llvm::LlvmCodegenBackend>
             at /Users/timch/rust/compiler/rustc_codegen_ssa/src/base.rs:808:42
  33: codegen_crate
             at /Users/timch/rust/compiler/rustc_codegen_llvm/src/lib.rs:318:18
  34: {closure#0}
             at /Users/timch/rust/compiler/rustc_interface/src/passes.rs:1267:29
  35: run<alloc::boxed::Box<dyn core::any::Any, alloc::alloc::Global>, rustc_interface::passes::start_codegen::{closure_env#0}>
             at /Users/timch/rust/compiler/rustc_data_structures/src/profiling.rs:844:9
  36: time<alloc::boxed::Box<dyn core::any::Any, alloc::alloc::Global>, rustc_interface::passes::start_codegen::{closure_env#0}>
             at /Users/timch/rust/compiler/rustc_session/src/utils.rs:17:50
  37: start_codegen
             at /Users/timch/rust/compiler/rustc_interface/src/passes.rs:1255:28
  38: codegen_and_build_linker
             at /Users/timch/rust/compiler/rustc_interface/src/queries.rs:33:43
  39: {closure#2}
             at /Users/timch/rust/compiler/rustc_driver_impl/src/lib.rs:383:18
  40: {closure#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
             at /Users/timch/rust/compiler/rustc_interface/src/passes.rs:1024:27
  41: {closure#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context.rs:1665:37
  42: {closure#0}<rustc_middle::ty::context::{impl#21}::enter::{closure_env#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:60:9
  43: try_with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_middle::ty::context::{impl#21}::enter::{closure_env#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/thread/local.rs:508:12
  44: with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_middle::ty::context::{impl#21}::enter::{closure_env#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/thread/local.rs:472:20
  45: enter_context<rustc_middle::ty::context::{impl#21}::enter::{closure_env#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context/tls.rs:57:9
  46: enter<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context.rs:1665:9
  47: create_global_ctxt<core::option::Option<rustc_interface::queries::Linker>, rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>>
             at /Users/timch/rust/compiler/rustc_middle/src/ty/context.rs:1872:13
  48: {closure#2}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
             at /Users/timch/rust/compiler/rustc_interface/src/passes.rs:991:9
  49: call_once<rustc_interface::passes::create_and_enter_global_ctxt::{closure_env#2}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, (&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, alloc::sync::Arc<rustc_data_structures::jobserver::Proxy, alloc::alloc::Global>, &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_env#2})>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/core/src/ops/function.rs:250:5
  50: call_once<(&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, alloc::sync::Arc<rustc_data_structures::jobserver::Proxy, alloc::alloc::Global>, &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_env#2}), dyn core::ops::function::FnOnce<(&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, alloc::sync::Arc<rustc_data_structures::jobserver::Proxy, alloc::alloc::Global>, &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_env#2}), Output=core::option::Option<rustc_interface::queries::Linker>>, alloc::alloc::Global>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/alloc/src/boxed.rs:2005:9
  51: create_and_enter_global_ctxt<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
             at /Users/timch/rust/compiler/rustc_interface/src/passes.rs:1032:5
  52: {closure#0}
             at /Users/timch/rust/compiler/rustc_driver_impl/src/lib.rs:340:22
  53: {closure#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>
             at /Users/timch/rust/compiler/rustc_interface/src/interface.rs:524:80
  54: call_once<(), rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/core/src/panic/unwind_safe.rs:274:9
  55: do_call<core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>, ()>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/panicking.rs:590:40
  56: catch_unwind<(), core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/panicking.rs:553:19
  57: catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>, ()>
             at /rustc/3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f/library/std/src/panic.rs:359:14
  58: {closure#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>
             at /Users/timch/rust/compiler/rustc_interface/src/interface.rs:524:23
  59: {closure#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>
             at /Users/timch/rust/compiler/rustc_interface/src/util.rs:209:17
  60: {closure#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>
             at /Users/timch/rust/compiler/rustc_interface/src/util.rs:163:24
  61: set<rustc_span::SessionGlobals, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>, ()>
             at /Users/timch/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/scoped-tls-1.0.1/src/lib.rs:137:9
  62: create_session_globals_then<(), rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>>
             at /Users/timch/rust/compiler/rustc_span/src/lib.rs:143:21
  63: {closure#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>
             at /Users/timch/rust/compiler/rustc_interface/src/util.rs:159:17
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 `/Users/timch/foo/rustc-ice-2025-11-19T06_37_14-7740.txt` to your bug report

note: compiler flags: --crate-type bin -C embed-bitcode=no -C debuginfo=2 -C split-debuginfo=unpacked -C incremental=[REDACTED]

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

query stack during panic:
end of query stack
error: could not compile `foo` (bin "foo")

@theemathas
Copy link
Contributor

The documentation for DispatchFromDyn also needs to be changed.

@dingxiangfei2009
Copy link
Contributor Author

which is not possible

I am not sure. We have an option to make it possible. The question is, would it be a bad idea?

In any case, let me add a stop-gap to disallow this case.

@dingxiangfei2009 dingxiangfei2009 force-pushed the dispatch-from-dyn-due-diligence branch from b7f84d2 to 8c95fd8 Compare November 19, 2025 10:31
@rustbot

This comment has been minimized.

@dingxiangfei2009 dingxiangfei2009 force-pushed the dispatch-from-dyn-due-diligence branch from 8c95fd8 to fdf32a0 Compare November 19, 2025 10:39
@jackh726 jackh726 added T-types Relevant to the types team, which will review and decide on the PR/issue. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 19, 2025
@jackh726
Copy link
Member

r? types

@rustbot rustbot assigned jackh726 and unassigned WaffleLapkin Nov 19, 2025
@dingxiangfei2009
Copy link
Contributor Author

Discussion under t-lang: #t-lang > Should we support dyn dispatch on `&Adt<_>`?

I think we are quite convinced that &Adt<_> as receiver is not dyn-compatible.

Comment on lines +73 to +74
impl<'a, T: ?Sized, U: ?Sized> DispatchFromDyn<&'a Ptr<U>> for &'a Ptr<T> {}
//~^ ERROR the trait `DispatchFromDyn` does not allow dispatch through references
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioning references here seems awfully specific. What about Box<Ptr<U>> or similar?

Copy link
Contributor Author

@dingxiangfei2009 dingxiangfei2009 Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am in the middle of updating the documentation on this trait.

Box<Ptr<U>> falls in the second case of the new documentation. We would foremost require Ptr<T>: DispatchFromDyn<Ptr<U>> among the other requirements.

.label = can't implement cross-crate trait for type in another crate
hir_analysis_dispatch_from_dyn_multiple_refs = the trait `DispatchFromDyn` does not allow dispatch through references
.note = the trait `DispatchFromDyn` may only be implemented when dispatch goes through at most one reference to a generic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this text not show up in the test error output?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot about a #[note] attribute on the error type. Now it should work.

@theemathas
Copy link
Contributor

theemathas commented Nov 20, 2025

This code doesn't compile with this PR. Should it?

#![feature(dispatch_from_dyn, arbitrary_self_types, unsize)]

use std::marker::{PhantomData, Unsize};
use std::ops::{DispatchFromDyn, Receiver};

pub struct Inner<T: ?Sized>(T);
#[repr(transparent)]
pub struct Outer<T: ?Sized>(PhantomData<T>, Inner<T>);

fn wrap<T: ?Sized>(x: &Inner<T>) -> &Outer<T> {
    // SAFETY: We're using repr(transparent)
    unsafe { &*(x as *const Inner<T> as *const Outer<T>) }
}

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

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

struct Thing(i32);
impl Trait for Thing {
    fn method(self: &Outer<Self>) {
        println!("{}", self.1.0.0);
    }
}

fn main() {
    let inner: &Inner<dyn Trait> = &Inner(Thing(1));
    let x: &Outer<dyn Trait> = wrap(inner);
    x.method();
}
error: the trait `DispatchFromDyn` does not allow dispatch through references
  --> src\main.rs:15:1
   |
15 | impl<'a, T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<&'a Outer<U>> for &'a Outer<T> {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: could not compile `foo` (bin "foo") due to 1 previous error

The new checks are we check the pair of constituent types for same
shapes structurally, and demand capability for dispatch for ADTs
as usual; and we demand source generic parameter to be unsized of
another for sanity.

Signed-off-by: Xiangfei Ding <[email protected]>
@dingxiangfei2009 dingxiangfei2009 force-pushed the dispatch-from-dyn-due-diligence branch from fdf32a0 to e0eee5f Compare November 26, 2025 18:23
@rustbot
Copy link
Collaborator

rustbot commented Nov 26, 2025

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@dingxiangfei2009
Copy link
Contributor Author

To answer the comment I have jotted down the reason that we do not want to compile the example in the trait documentation.

@rust-log-analyzer
Copy link
Collaborator

The job aarch64-gnu-llvm-20-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
- error[E0377]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
+ error[E0277]: the trait bound `T: Unsize<T>` is not satisfied
11   --> $DIR/dispatch-from-dyn-blanket-impl.rs:6:1
12    |
13 LL | impl<T> std::ops::DispatchFromDyn<T> for T {}

-    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unsize<T>` is not implemented for `T`
+    |
+    = note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
+ help: consider restricting type parameter `T` with unstable trait `Unsize`
+    |
+ LL | impl<T: std::marker::Unsize<T>> std::ops::DispatchFromDyn<T> for T {}
+    |       ++++++++++++++++++++++++
15 
16 error: aborting due to 2 previous errors
17 

---
To only update this specific test, also pass `--test-args traits/dispatch-from-dyn-blanket-impl.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/traits/dispatch-from-dyn-blanket-impl.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/traits/dispatch-from-dyn-blanket-impl" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
##[error]  --> /checkout/tests/ui/traits/dispatch-from-dyn-blanket-impl.rs:6:6
   |
LL | impl<T> std::ops::DispatchFromDyn<T> for T {}
   |      ^ type parameter `T` must be used as the type parameter for some local type
   |
   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
   = note: only traits defined in the current crate can be implemented for a type parameter

error[E0277]: the trait bound `T: Unsize<T>` is not satisfied
##[error]  --> /checkout/tests/ui/traits/dispatch-from-dyn-blanket-impl.rs:6:1
   |
LL | impl<T> std::ops::DispatchFromDyn<T> for T {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unsize<T>` is not implemented for `T`
   |
   = note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
help: consider restricting type parameter `T` with unstable trait `Unsize`
   |
LL | impl<T: std::marker::Unsize<T>> std::ops::DispatchFromDyn<T> for T {}
   |       ++++++++++++++++++++++++

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0210, E0277.

@theemathas
Copy link
Contributor

theemathas commented Nov 26, 2025

@dingxiangfei2009 Your comment in the code unfortunately does not answer my latest comment in this PR. My comment does not involve a double pointer indirection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

7 participants