Skip to main content

Module miniextendr_impl_trait

Module miniextendr_impl_trait 

Source
Expand description

§#[miniextendr] on trait impls - Trait Implementation Registration

This module handles #[miniextendr] applied to trait implementations, generating the vtable static for cross-package trait dispatch, plus optional R-callable wrappers for direct method access.

§Overview

When #[miniextendr] is applied to an impl Trait for Type block, it:

  1. Detects the trait from the impl syntax (no attribute args needed)
  2. Generates vtable static using declaration-provided layout and callbacks
  3. Generates C wrappers for each trait method (for R .Call access)
  4. Generates R wrapper code for the trait methods
  5. Passes through the original impl block unchanged

§Usage

ⓘ
use miniextendr_api::miniextendr;

// The trait must have been defined with #[miniextendr]
// which generates __Counter_build_vtable::<T>()

struct MyCounter { value: i32 }

#[miniextendr]
impl Counter for MyCounter {
    fn value(&self) -> i32 {
        self.value
    }
    fn increment(&mut self) {
        self.value += 1;
    }
    fn add(&mut self, n: i32) {
        self.value += n;
    }
}

Generates (conceptually):

ⓘ
// Original impl block (passed through)
impl Counter for MyCounter {
    fn value(&self) -> i32 { self.value }
    fn increment(&mut self) { self.value += 1; }
    fn add(&mut self, n: i32) { self.value += n; }
}

// Generated vtable static (crate-prefixed for webR cross-package symbol
// uniqueness — #1273; example assumes a crate named `mypkg`). Its local
// repr(C) type reproduces Counter's declared callback order and types.
pub static __VTABLE_mypkg_Counter_FOR_MyCounter: __VTABLE_mypkg_Counter_FOR_MyCounter_Layout =
    __VTABLE_mypkg_Counter_FOR_MyCounter_Layout {
        value: <MyCounter as Counter>::__Counter_value_shim,
        increment: <MyCounter as Counter>::__Counter_increment_shim,
        add: <MyCounter as Counter>::__Counter_add_shim,
    };

§How It Works

  1. Parse impl Trait for Type to extract trait path and concrete type
  2. Generate vtable static name: __VTABLE_{crate}_{Trait}_FOR_{Type}
  3. Obtain the declaration’s ABI tag and ordered callback fields through its metadata macro
  4. Initialize the local layout with associated or concrete generic callbacks

§Trait Detection

The macro reads the trait directly from the impl syntax:

ⓘ
#[miniextendr]
impl path::to::Counter for MyType { ... }
//   ^^^^^^^^^^^^^^^^^ detected automatically

No extra arguments are needed; the trait path is explicit in the impl syntax.

§Name Generation

  • Vtable static: __VTABLE_{crate}_{Trait}_FOR_{Type} (case-preserving; {crate} is the consuming crate’s name, prefixed for webR cross-package symbol uniqueness — #1273)
  • Local vtable type: the static name with _Layout appended

For impl foo::Counter for my_mod::MyType in a crate named mypkg:

  • Static: __VTABLE_mypkg_Counter_FOR_MyType
  • Callback: <my_mod::MyType as foo::Counter>::__Counter_value_shim

§Integration with ExternalPtr / TypedExternal

The generated vtable static is automatically registered via linkme distributed slices.

ⓘ
#[derive(ExternalPtr)]
struct MyCounter { value: i32 }

#[miniextendr]
impl Counter for MyCounter { /* ... */ }

ExternalPtr<T> provides the type identity for the external pointer. Trait dispatch is wired automatically.

§Thread Safety

The generated vtable is a static constant, safe to access from any thread. Trait shims now mirror inherent impls: instance methods stay on the main thread, while static trait methods run on the worker thread unless main_thread is explicitly requested.

Modules§

defaults 🔒
Instantiate omitted default-method signatures for concrete trait wrappers.
method_context 🔒
Shared per-method context for trait-impl R wrapper generation.
r_wrappers 🔒
R wrapper generation for trait methods across all class systems.
vtable 🔒
Vtable static generation, C wrapper generation, and method attribute parsing for trait impls.

Structs§

ImplWithMetadata 🔒
Populated impl plus declaration metadata, supplied by the trait’s macro. Keep this as Rust syntax so method bodies, generics and author attributes pass through without a second bespoke representation.
TpieInput 🔒
Input to the __mx_trait_impl_expand! proc macro.
TpieMethod 🔒
A single method entry in TPIE metadata.
TraitAbiMetadata 🔒
The declaration’s ABI layout and tag, carried through its metadata macro. An impl must not reconstruct these from an imported or re-exported path.
TraitConst 🔒
Parsed associated constant from a trait impl block.
TraitMethod 🔒
Parsed method from a trait impl block.

Functions§

expand_miniextendr_impl_trait
Expand #[miniextendr] applied to a trait implementation.
expand_tpie
Entry point for the __mx_trait_impl_expand! proc macro.
extract_trait_and_type 🔒
Extract the trait path and concrete type from an impl block.
generate_tpie_invocation 🔒
Request declaration metadata for an empty trait impl.
rewrite_self_in_params 🔒
Rewrite Self → concrete type in a method signature’s parameters.
rewrite_self_type 🔒
Recursively replace Self with the concrete type in a type tree.
trait_method_body_lines 🔒
Generate R function body lines that capture the .Call() result in .val, check for a tagged rust_condition_value, and return .val. raise_default is the raise helper’s fallback call (CallAttribution::raise_default).
type_to_symbol_name 🔒
Convert a type to a case-preserving identifier-safe name.
unwrap_group_type 🔒
Unwrap invisible Group tokens from macro_rules! $t:ty captures.