Skip to content

Gate or Implement dynamic upcasting conversion #3157

Open
@liamnaddell

Description

@liamnaddell

Summary

This issue is created because of a comment under #3124.

Background: https://rust-lang.github.io/rfcs/3324-dyn-upcasting.html

As far as I understand, internally, a dynamic reference is a vtable containing all the required struct items, and method pointers. Since rust supports parent and child traits (supertraits), I believe casting from &dyn Child -> &dyn parent requires pruning the Child's vtable to match the Parent's vtable, as far as gccrs is concerned. Rust does not have a specified ABI in this case, so we do not need to conform to some specific vtable layout.

As of writing, rustc stable does not support dynamic upcasting, but the RFC is implemented in nightly rust. Meaning it's likely we will have to support this at some point to remain compliant with rustc.

Reproducer

I tried this code:

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

struct Foo {
    my_int: u32,
}

trait Parent {
    fn parent(&self) -> bool;
}

trait Child : Parent {
    fn child(&self);
}

impl Parent for Foo {
    fn parent(&self) -> bool {
        // Call supertrait method
        return true;
    }
}

impl Child for Foo {
    fn child(&self) {
        let _ = self;
    }
}

pub fn main() {
    let a = Foo{ my_int: 0xf00dfeed};
    let b: &dyn Child = &a;

    let c: &dyn Parent = b;

    c.parent();
}

Does the code make use of any (1.49) nightly feature ?

  • Nightly

Godbolt link

No response

Actual behavior

Crash in the gimple verifier

Expected behavior

Either we need to gate this conversion until rustc stabilizes the behavior, or implement the feature once stabilized.

GCC Version

c5f9d6d

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions