Skip to content

Inconsistent vtable layout with HRTBs #135316

Closed
@steffahn

Description

@steffahn
trait Supertrait<T> {
    fn _print_numbers(&self, mem: &[usize; 100]) {
        println!("{mem:?}");
    }
}
impl<T> Supertrait<T> for () {}

trait Trait<T, U>: Supertrait<T> + Supertrait<U> {
    fn say_hello(&self, _: &usize) {
        println!("Hello!");
    }
}
impl<T, U> Trait<T, U> for () {}

fn main() {
    (&() as &'static dyn for<'a> Trait<&'static (), &'a ()>
        as &'static dyn Trait<&'static (), &'static ()>)
        .say_hello(&0);
}

(playground)

example output (shortened):

[0, 2338324182462507040, 7738151096083899748, 438881233243824, 439624262586284, 439667212259195, 439765996507179…

so apparently, we're calling _print_numbers actually, because the vtable of dyn for<'a> Trait<&'static (), &'a ()> and dyn Trait<&'static (), &'static ()> aren't compatible.

@rustbot label I-unsound, T-compiler, A-trait-objects, A-coercions, A-higher-ranked


This code example is technically a regression, starting to misbehave somewhere between 1.55 and 1.56 (haven't further bisected yet…)

Metadata

Metadata

Labels

A-coercionsArea: implicit and explicit `expr as Type` coercionsA-dyn-traitArea: trait objects, vtable layoutA-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)C-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-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.

Type

No type

Projects

Status

Completed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions