Skip to content

Boxed trait types with NoContext emit undeclared types in trait object structs #25

Description

@EngineersBox

Background

I've got some definitions for brokers with consumers and producers that accept/return a dummy trait object. Both the consumers, produces and returned object a context-less Boxed trait objects (i.e. NoContext). Here is the trait definitions for consumers and producers (assume there is similar trait defs on the broker to create a boxed no-context consumer or producer):

#[cglue_trait]
pub trait ContextData {
    fn id(&self) -> usize;
}

#[cglue_trait]
pub trait ContextConsumer {
    #[doc = "Blocks the current thread, waiting for data to appear"]
    #[int_result]
    fn poll(&mut self) -> Result<ContextDataBox<'static>, GenericError>;

    #[doc = "Attempts to return data if available, otherwise a `GenericError::Retry` error"]
    #[int_result]
    fn try_poll(&mut self) -> Result<ContextDataBox<'static>, GenericError>;
}

#[cglue_trait]
pub trait ContextProducer {
    fn push(&mut self, data: ContextDataBox<'static>) -> Option<GenericError>;
    fn try_push(&mut self, data: ContextDataBox<'static>) -> Option<GenericError>;
}

Problem

As you can see the trait objects returned are ContextDataBox<'static> that imply NoContext for the context in the CGlueObjContainer. When emitting the bindings in C (or C++), I get missing definitions for NoContext

/**
 * Simple CGlue trait object.
 *
 * This is the simplest form of CGlue object, represented by a container and vtable for a single
 * trait.
 *
 * Container merely is a this pointer with some optional temporary return reference context.
 */
typedef struct CGlueTraitObj_CBox_c_void_____ContextConsumerVtbl_CGlueObjContainer_CBox_c_void_____NoContext__ContextConsumerRetTmp_NoContext___________NoContext__ContextConsumerRetTmp_NoContext {
    const struct ContextConsumerVtbl_CGlueObjContainer_CBox_c_void_____NoContext__NoContextConsumerRetTmp_NoContext *vtbl;
    struct CGlueObjContainer_CBox_c_void_____NoContext__NoContextConsumerRetTmp_NoContext container; <-- Error here
} CGlueTraitObj_CBox_c_void_____ContextConsumerVtbl_CGlueObjContainer_CBox_c_void_____NoContext__ContextConsumerRetTmp_NoContext___________NoContext__ContextConsumerRetTmp_NoContext;

The error appears in the trait object structure definition, the specific daignostic message is Field has incomplete type 'struct CGlueObjContainer_CBox_c_void_____NoContext__NoContextDataRetTmp_NoContext'.

I cannot find a matching definition within the file, there are other wrapping definitions or typedefs with that type as a subset of the name, etc but no concrete definition (which arguably, make sense since there is no context object).

Configs

cbindgen.toml

language = "C"
include_guard = "_KAIROS_H_"
pragma_once = true
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Do not modify this manually. */"
include_version = true
cpp_compat = true
tab_width = 4
documentation = true
documentation_style = "Doxy"
style = "both"

[export]
include = [
    "KAIROS_PLUGIN_API_VERSION",
    "KAIROS_PLUGIN_DESCRIPTOR",
    "SchedulerDescriptor",
    "SchedulerPluginArcBox",
    "WorkerGroupProviderBox",
    "WorkerGroupBox",
    "LoggerDrainBox",
    "ContextPluginArcBox",
    "ContextBrokerArcBox",
    "ContextSubscriberBox",
    "ContextDataBox",
    "BrokerRetrieverArcBox",
    "FFIBrokerRetriever",
    "VersionNumber",
]

[export.rename]

[export.body]

[export.mangle]

[fn]
sort_by = "Name"

[const]
allow_static_const = true
allow_constexpr = true 
sort_by = "Name"

[macro_expansion]
bitflags = true

[parse]
parse_deps = true
include = ["cglue", "kairos"]

[parse.expand]
crates = [
    "cglue",
    "kairos",
    "kairos-common",
    "kairos-workers",
    "kairos-context",
    "kairos-scheduler"
]

cglue.toml:

default_container = "Box"
default_context = "Arc"

Notes

There could be a better way to do this, or I'm misunderstanding how codegen should be configured for this.

It feels like I should provide some concrete type definition for what NoContext will be emitted as, if it takes an actual value, or should otherwise be omitted from the definitions. The former seems more reasonable as type layouts go and structural consistency, i.e. a NULL value in void* field.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions