gccrs icon indicating copy to clipboard operation
gccrs copied to clipboard

Dynamic objects support inheritance

Open philberty opened this issue 3 years ago • 4 comments

I tried this code:

extern "C" {
    fn printf(s: *const i8, ...);
}

struct Foo(i32);
trait Bar {
    fn baz(&self);
}

trait Baz : Bar {
    fn qux(&self);
}

impl Bar for Foo {
    fn baz(&self) {
        unsafe {
            let a = "baz %i\n\0";
            let b = a as *const str;
            let c = b as *const i8;

            printf(c, self.0);
        }
    }
}

impl Baz for Foo {
    fn qux(&self) {
        unsafe {
            let a = "baz %i\n\0";
            let b = a as *const str;
            let c = b as *const i8;

            printf(c, self.0);
        }
    }
}


fn dynamic_dispatch(t: &dyn Baz) {
    t.baz();
    t.qux();
}

pub fn main() {
    let a;
    a = &Foo(123);
    dynamic_dispatch(a);
}

I expected to see this happen: compile without error

Instead, this happened:

<source>:40:7: error: failed to resolve method for 'baz'
   40 |     t.baz();
      |       ^
<source>:40:5: error: failed to type resolve expression
   40 |     t.baz();
      |     ^
rust1: error: bounds not satisfied for dyn [example::Baz] 'example::Bar' is not satisfied

Meta

  • What version of Rust GCC were you using, git sha if possible. 83bfbf0746c87b641754697a3c8e9f7a7cb08aa9

philberty avatar Feb 09 '22 11:02 philberty

You can't get from &dyn Baz to &dyn Bar on stable rustc. What happens here is that the vtable contains all methods of all super traits. On nightly rustc it also contains pointers to vtables of super traits as necessary to allow upcasting trait objects to super traits.

bjorn3 avatar Feb 09 '22 12:02 bjorn3