Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for trait objects #72

Closed
rbartlensky opened this issue Feb 21, 2019 · 6 comments · Fixed by #160
Closed

Support for trait objects #72

rbartlensky opened this issue Feb 21, 2019 · 6 comments · Fixed by #160

Comments

@rbartlensky
Copy link

Can you wrap a trait object in a Gc? I would like to be able to write something like this. As a workaround, I am currently creating a Gc<Box<dyn MyTrait>>, but I don't really like the indirection. I am trying to use Gc the way you would use a Box or Rc with trait objects.

@Manishearth
Copy link
Owner

No, because we don't know how to trace it.

You can write such a thing in a wrapped struct with a custom implementation of Trace if you want.

@rbartlensky
Copy link
Author

Correct me if I am wrong, but even if I create a wrapper, it will still contain some sort of pointer to MyTrait. I tried what you suggested, but I am not sure that I got it right.

pub struct DynWrapper<T: ?Sized + Trace + Finalize> {
    data: T,
}

impl<T: Trace> DynWrapper<T> {
    pub fn new(data: T) -> Self {
        DynWrapper { data  }
    }
}

But this doesn't work with trait objects, unless I have a */&/Box/Rc T instead of a plain T. I am trying to avoid the extra heap allocation, because Gc already does one.

@Manishearth
Copy link
Owner

No, you have to do this on a per-trait-object basis

pub struct MyTraitWrapper {
   inner: Box<Trait>
}

and your Trait needs to inherit from Trace (you can't do Box<Trait+Trace> sadly). You can also create a new trait that inherits from both traits.

If you want to avoid the heap allocation you can do the following:

pub struct MyTraitWrapper {
  inner: Trait

which is also a dynamically sized type and can be directly placed inside Gc. It's tricker to construct though, you'll likely need a constructor that directly returns Gc<MyTraitWrapper>

@rbartlensky
Copy link
Author

Thank you for your help. I think I will stick with your first suggestion.

@andersk
Copy link
Collaborator

andersk commented Dec 30, 2020

The original code actually just works in nightly Rust with the nightly crate feature, due to CoerceUnsized (67cc6e2).

@andersk
Copy link
Collaborator

andersk commented Dec 22, 2022

With the nightly crate feature, #160 adds a conversion from Box<dyn Trait> to Gc<dyn Trait>. So I think trait objects are now supported as well as they can be.

The tracking issue for the required unstable Rust feature is

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants