8000 Feature request: Blanket Implementation for the trait · Issue #19 · h33p/cglue · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Feature request: Blanket Implementation for the trait #19

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. 8000 We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
stevefan1999-personal opened this issue Sep 10, 2024 · 1 comment
Open
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@stevefan1999-personal
Copy link

This code:

use type_uuid::{TypeUuid};
use cglue::*;


#[cglue_trait]
pub trait UUIDIdentifiable {
    fn uuid(&self) -> UUID;
}

impl<T: TypeUuid> UUIDIdentifiable for T {
    fn uuid(&self) -> UUID {
        UUID { value: <Self as TypeUuid>::UUID }
    }
}


#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct UUID {
    value: [u8; 16],
}


#[repr(C)]
#[derive(TypeUuid)]
#[uuid = "d4adfc76-f5f4-40b0-8e28-8a51a12f5e46"]
pub struct MyType;

Is currently not able to compile:

   Compiling vtable_uuid v0.1.0 (F:\rust\vtable_uuid)
error[E0119]: conflicting implementations of trait `UUIDIdentifiable`
  --> src/main.rs:5:1
   |
5  | #[cglue_trait]
   | ^^^^^^^^^^^^^^ conflicting implementation
...
10 | impl<T: TypeUuid> UUIDIdentifiable for T {
   | ---------------------------------------- first implementation here
   |
   = note: this error originates in the attribute macro `cglue_trait` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0119`.
error: could not compile `vtable_uuid` (bin "vtable_uuid") due to 1 previous error

Indeed there is another blanket implementation that makes it not okay:

        impl<
            'cglue_a,
            CGlueO: 'cglue_a + UUIDIdentifiableVtblGet<'cglue_a>
                + UUIDIdentifiableOpaqueObj<'cglue_a>
                + UUIDIdentifiableAssocBind<Assocs = ()>
                + ::cglue::trait_group::GetVtblBase<
                    UUIDIdentifiableVtbl<
                        'cglue_a,
                        <Self as ::cglue::trait_group::GetContainer>::ContType,
                    >,
                >,
        > UUIDIdentifiable for CGlueO {
            #[inline(always)]
            fn uuid(&self) -> UUID {
                let __cglue_vfunc = self.get_vtbl().uuid;
                let cont = self.ccont_ref();
                let mut ret = __cglue_vfunc(cont);
                ret
            }
        }

This feature would be very useful, so we can now attach UUID to a struct and then put them into a universal container for applications to search in runtime. This is adapted by Microsoft in their COM IPC mechanism with a vtable hack, and also UEFI implementation

@h33p
Copy link
Owner
h33p commented Apr 28, 2025

I had a crack at this, and I think I figured out a way to work around this on CGlue's side:

#[repr(C)]
struct CGlue<T>(pub T);

impl<T: GetVtbl<MagicVtbl<()>>> Magic for CGlue<T> {
    fn magic(&self) {
        let v = self.0.get_vtbl();
        let p = self.0.get_obj();
        (v.magic)(p)
    }
}

impl<T: Magic> Magic for &T {
    fn magic(&self) {
        T::magic(*self)
    }
}

Background:

Currently, cglue codegen spits out implementation for CGlueO, which conflicts with any blanket impl. I did this for a generic, instead of CGlueObj<...>, because I needed to support arbitrary trait_group! objects. However, in both cases I can wrap around a shared object, like CGlue<T>, which can then limit the generic impl to just cglue objects. Should be in for 0.4.

@h33p h33p self-assigned this Apr 28, 2025
@h33p h33p added bug Something isn't working enhancement New feature or request labels Apr 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants
0