Skip to main content

Module miniextendr_trait

Module miniextendr_trait 

Source
Expand description

§Trait Support for #[miniextendr]

This module handles #[miniextendr] applied to trait definitions, generating the ABI infrastructure for cross-package trait dispatch.

§Overview

When #[miniextendr] is applied to a trait, it generates:

  1. Type tag constant (TAG_<TraitName>) - 128-bit identifier for runtime type checking
  2. Vtable struct (<TraitName>VTable) - Function pointer table for method dispatch
  3. View struct (<TraitName>View) - Runtime wrapper combining data pointer and vtable
  4. Method shims - extern "C" functions that convert SEXP arguments and call methods
  5. Vtable builder - __<trait>_build_vtable::<T>() for impl blocks

§Usage

#[miniextendr]
pub trait Counter {
    fn value(&self) -> i32;
    fn increment(&mut self);
    fn add(&mut self, n: i32);
}

Generates (conceptually):

// Original trait (passed through)
pub trait Counter {
    fn value(&self) -> i32;
    fn increment(&mut self);
    fn add(&mut self, n: i32);
}

// Type tag for runtime identification
pub const TAG_COUNTER: mx_tag = mx_tag::new(0x..., 0x...);

// Vtable with one entry per method
#[repr(C)]
pub struct CounterVTable {
    pub value: mx_meth,
    pub increment: mx_meth,
    pub add: mx_meth,
}

// View combining data pointer and vtable
#[repr(C)]
pub struct CounterView {
    pub data: *mut std::ffi::c_void,
    pub vtable: *const CounterVTable,
}

// Shim for each method
unsafe extern "C" fn __counter_value_shim<T: Counter>(
    data: *mut c_void, argc: i32, argv: *const SEXP
) -> SEXP {
    // 1. Check arity
    // 2. Cast data to &T
    // 3. Call method
    // 4. Convert result to SEXP
    // 5. Catch panics
}

// Builder to create vtable for a concrete type
pub const fn __counter_build_vtable<T: Counter>() -> CounterVTable {
    CounterVTable {
        value: __counter_value_shim::<T>,
        increment: __counter_increment_shim::<T>,
        add: __counter_add_shim::<T>,
    }
}

§Supported Method Signatures

Methods must follow these constraints:

  • Receiver: &self or &mut self for instance methods, or none for static methods
  • Arguments: Types that implement TryFromSexp
  • Return: Types that implement IntoR, or ()
  • No generics: Methods cannot have generic type parameters
  • No async: Async methods are not supported
  • Static methods: Methods without a receiver are allowed and resolved at compile time (they don’t go through the vtable)

§Default Methods

Default method implementations are supported. The vtable builder will use the default implementation if the concrete type doesn’t override it.

#[miniextendr]
pub trait Counter {
    fn value(&self) -> i32;

    // Default implementation - included in vtable
    fn is_zero(&self) -> bool {
        self.value() == 0
    }
}

§Error Handling

Method shims handle errors as follows:

  • Arity mismatch: Raises R error (“expected N arguments, got M”)
  • Type conversion failure: Raises R error with the error message
  • Panic: Caught via with_r_unwind_protect, converted to R error

§Thread Safety

All generated shims are main-thread only. They do not route through with_r_thread because R invokes .Call on the main thread.

Structs§

ExtraBounds 🔒
Extra trait bounds inferred from method signatures.
MethodInfo 🔒
Information extracted from a trait method for code generation.

Functions§

build_where_predicates 🔒
Build combined where predicates from the trait’s own where clause and computed extra bounds.
compute_extra_bounds 🔒
Compute extra bounds needed for the shim and build_vtable functions.
expand_trait
Expand #[miniextendr] applied to a trait definition.
extract_method_info 🔒
Extract method information from a trait method definition.
generate_method_shim 🔒
Generate a method shim function for a trait method.
generate_trait_abi 🔒
Generate the ABI infrastructure for a trait.
generate_view_method 🔒
Generate a method wrapper for the View struct.
param_is_self_ref 🔒
Check if a parameter type is &Self or &mut Self.
rewrite_self_in_type 🔒
Rewrite Self and Self::AssocType in a type tree to use __ImplT.
type_contains_ident 🔒
Check if a type syntactically contains a specific identifier.
type_contains_self 🔒
Check if a type syntactically contains Self.
type_contains_self_assoc 🔒
Check if a type syntactically contains Self::AssocType for a given associated type name.
validate_method 🔒
Validate a single trait method for ABI compatibility.
validate_trait 🔒
Validate that the trait meets requirements for ABI generation.