Open
Labels
A-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layoutA-type-systemArea: Type systemArea: Type systemC-bugCategory: This is a bug.Category: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityS-has-bisectionStatus: A bisection has been found for this issueStatus: A bisection has been found for this issueT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant 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.Relevant to the types team, which will review and decide on the PR/issue.
Description
In the following code:
#![forbid(unsafe_code)]
#![allow(dead_code)]
// `Sub` has a where clause that holds for `S` but not for `dyn Sub<..>` itself.
// Codegen then takes `dyn Sub<..>` for a type that "can never be constructed"
// and stops computing vtable slots for it.
trait Holds {}
impl<'a> Holds for &'a S {}
trait A<T> { fn a(&self, t: T) -> T; }
trait B<T, U> { fn b(&self, t: T) -> U; }
trait Sub<T, U>: A<T> + B<T, U> where for<'a> &'a Self: Holds {}
struct S;
impl<T> A<T> for S { fn a(&self, t: T) -> T { t } }
impl<T, U> B<T, U> for S { fn b(&self, _: T) -> U { unreachable!() } }
impl<T, U> Sub<T, U> for S {}
// Should load the `B` vptr out of the `Sub` vtable. Keeps the `Sub` vtable instead.
#[inline(never)]
fn upcast<'a, T, U>(x: &'a dyn Sub<T, U>) -> &'a dyn B<T, U> { x }
// Slot 3 of the `Sub` vtable is `A::a`, so `.b(t)` runs `A::a` and hands `t` back as a `U`.
fn transmute<T, U>(t: T) -> U { upcast::<T, U>(&S).b(t) }
pub fn main() {
let x = 5u8;
let addr: usize = transmute(&x);
println!("&u8 as usize: {addr:#x}");
let r: &u64 = transmute(0x10usize);
println!("{r}"); // reads address 0x10
}I expected to see this happen: a runtime panic
Instead, this happened: segmentation fault from dereferencing 0x10
Related, but less exciting and with a different root cause:
#![allow(dead_code)]
// Second route, no upcast: a call of a supertrait method on `dyn Sub`.
// The first slot of `A` in the vtable is reported as 0, so `a` (third method) is
// looked up in slot 2, which holds the alignment of `S`.
trait Holds {}
impl<'a> Holds for &'a S {}
trait A { fn a0(&self) {} fn a1(&self) {} fn a(&self) -> u32; }
trait Sub: A where for<'a> &'a Self: Holds {}
struct S;
impl A for S { fn a(&self) -> u32 { 7 } }
impl Sub for S {}
#[inline(never)]
fn call(x: &dyn Sub) -> u32 { x.a() }
pub fn main() {
println!("{}", call(&S));
}I expected to see this happen: prints 7
Instead, this happened: segmentation fault
Meta
Nightly: https://rust.godbolt.org/z/M8Wxz6qjh
1.99.0: https://rust.godbolt.org/z/nxM1We8G5
This bisects to 1.86.0, Claude is guessing it's due to #136311 based on the title, I have not verified that.
Reacted by Max and León Orell Valerian Liehr
Metadata
Metadata
Assignees
Labels
A-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layoutA-type-systemArea: Type systemArea: Type systemC-bugCategory: This is a bug.Category: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityS-has-bisectionStatus: A bisection has been found for this issueStatus: A bisection has been found for this issueT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant 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.Relevant to the types team, which will review and decide on the PR/issue.
Type
Projects
- StatusShow more project fieldsopen/unblocked
Activity
clubby789 commentedon Oct 18, 2026
Confirmed manually that this is #136311
jieyouxu commentedon Oct 19, 2026
zachs18 commentedon Oct 20, 2026
You can also get an ICE out of this if you remove
#[inline(never)]fromupcastwith optimizations enabled. (godbolt link)@rustbot label +I-ICE
repro that causes internal compiler error
rustbot commentedon Oct 21, 2026
Assigning P-medium (discussion on Zulip)