Skip to content

Object safety does not consider supertraits #18959

Closed
@emberian

Description

@emberian

The following code either aborts or segfaults for me, depending on if I'm in gdb or not, on Linux:

pub trait ExtTrait for Sized? {
    fn ext(&self);
}

pub trait Foo for Sized? {
    fn foo<Sized? T>(&mut self, ext_thing: &T) where T: ExtTrait;
}

pub trait Bar for Sized?: Foo { }

impl<'a> Foo for Bar + 'a {
    fn foo<Sized? T>(&mut self, ext_thing: &T) where T: ExtTrait {
        (*self).foo(ext_thing);
    }
}

impl<T: Foo> Bar for T { }

pub struct Thing;

impl Foo for Thing {
    fn foo<Sized? T>(&mut self, _: &T) where T: ExtTrait {
        println!("Thing::Foo::foo begin");
    }
}

pub struct Supporting;

impl ExtTrait for Supporting {
    fn ext(&self) {
        println!("Supporting::ExtTrait::ext");
    }
}

fn main() {
    let mut thing = Thing;
    let ext_thing = Supporting;
    let test: &mut Bar = &mut thing;

    test.foo(&ext_thing);
}

With optimizations, main becomes

define internal void @_ZN4main20h337c4f395fd4e2e64caE() unnamed_addr #0 {
entry-block:
  tail call void @llvm.trap()
  unreachable
}

Which means we're doing something very bad when translating this code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions