Skip to main content

CallAttribution

Enum CallAttribution 

Source
pub enum CallAttribution {
    Wrapper,
    Caller,
    Argument,
    NoCall,
    Generic,
    GenericEager,
}
Expand description

Which frame a generated wrapper hands to .Call(.., .call = ..) and uses as the raise fallback (.miniextendr_raise_condition(.val, <default>)).

Variants§

§

Wrapper

.call = sys.call(): the wrapper’s own call, as written (default).

§

Caller

.call = .mx_call, where the wrapper body first binds .mx_call <- .miniextendr_caller_call(): the caller’s call as written, resolved by the preamble helper in miniextendr-api/src/registry.rs (one line per wrapper since #1552, four before). The helper looks two frames up the calling chain for the wrapper’s caller. It falls back to the wrapper’s own call when there is no parent frame (top level) or the parent frame is not a closure: eval()’d code such as a testthat block or source() has the eval primitive as its frame function, whose call names eval. For a noexport entry point behind a hand-written R function (#[miniextendr(noexport, call = caller)]).

A standalone wrapper with this attribution also takes a trailing .call = NULL formal (CallAttribution::formal, #1613), which the prelude hands to the helper: a hand-written helper sitting between the public function and the entry point passes its own caller’s frame (call = parent.frame() in the helper’s formals, .call = call in its body), and the condition names the public function. .call also takes a call object, used as is. S3 methods keep the zero-argument prelude: a trailing formal would break generic/method consistency.

§

Argument

.call = .mx_call, where the wrapper body first binds .mx_call <- if (is.null(.call)) sys.call() else .miniextendr_caller_call(.call, own = TRUE): the wrapper’s own call, as for CallAttribution::Wrapper, unless the caller passes another as the trailing .call = NULL formal (#1834). Selected by #[miniextendr(call_arg)] on a standalone function, exported or not: an R function composing exported functions (applying them through do.call(), say) passes .call = environment() and every condition names its own call. The helper resolves a frame or a call as under CallAttribution::Caller; a frame no closure owns gives the wrapper’s own call. The success path without .call costs one is.null(). Never parsed from call = ...: it is wrapper attribution plus the formal, so a Call marker reads the resolved call.

§

NoCall

.call = FALSE: no call at all (#1851). Selected by #[miniextendr(call = none)] on a standalone function (an S3 method included) or by the crate default call_attribution = "none", which applies to every standalone function. Every condition the wrapper raises then has a NULL conditionCall(), like R’s call. = FALSE: the R-side checks and the match_arg helpers are passed NULL, the slot carries FALSE, the marker the raise helper already reads as “no call” (what call = none on a condition macro writes, see ConditionCall::None), and the raise fallback is NULL. There is no marker spelling: a Call / CallerCall parameter receives the call, and this attribution has none, so either one is a compile error with it, as is call_arg (whose .call would have nothing to replace).

§

Generic

.call = environment(): the wrapper’s own frame, turned into a call only when a condition is raised (#1851). The attribution of every generated S3 method that would otherwise be wrapper: a standalone s3(...) function, an impl-block or trait s3 / vctrs method (CallAttribution::for_s3_method). The raise helper and .miniextendr_arg_error resolve the frame with .miniextendr_frame_call (miniextendr-api/src/registry.rs), which names the generic the user called when R dispatched the method (.Generic is bound in the frame: summary(x, a = 1) for summary.cls(x, a = 1), x[i] for `[.cls`(x, i)) and writes a replacement generic’s call as the assignment, x$name <- value, without the value R passed. A direct call of the method keeps the method’s name. The success path evaluates environment() instead of sys.call(), the same cost; the rewrite runs only on a raise.

§

GenericEager

.call = .mx_call, where the wrapper body first binds .mx_call <- .miniextendr_frame_call(environment()): the CallAttribution::Generic call resolved before the .Call(), for an S3 method with a Call parameter, whose C wrapper binds it from the slot and so needs a call object there (#1851). Costs the frame scan on every call, so only the marker selects it.

Implementations§

Source§

impl CallAttribution

Source

pub fn parse_name(name: &str) -> Option<Self>

The spelling shared by the attribute (call = wrapper | caller | none) and the crate default (call_attribution = "wrapper" | "caller" | "none").

Source

pub fn name(self) -> &'static str

The attribute spelling of this attribution. CallAttribution::Argument is wrapper attribution with the call_arg option, and the two S3 forms are wrapper attribution on a dispatched method, so all three share wrapper’s spelling.

Source

pub fn marker_name(self) -> Option<&'static str>

The parameter marker type that selects this attribution (#1566): Call for wrapper, CallerCall for caller. none has no marker: a marker receives the call, and none passes none.

Source

pub fn for_s3_method(self, has_call_marker: bool) -> Self

The attribution of a generated S3 method (#1851): wrapper becomes CallAttribution::Generic, or CallAttribution::GenericEager when the method takes a Call parameter (has_call_marker), which needs the call resolved before the .Call(). caller and none are explicit choices and stay; Argument never reaches an S3 method (call_arg is refused on them).

Source

pub fn resolve( marker: Option<Self>, attribute: Option<Self>, crate_default: Option<Self>, internal_entry: bool, ) -> Self

Resolve a standalone function’s attribution from its three spellings (#1566), most specific first: the Call / CallerCall parameter marker, the call = wrapper | caller | none attribute, the crate’s [package.metadata.miniextendr] call_attribution default and finally the framework default, wrapper. A crate default of caller applies to internal entry points (noexport / internal) only; an exported function’s caller is arbitrary user code, so it keeps wrapper. A crate default of none applies to every standalone function, like wrapper (#1851). The explicit spellings are validated before this runs (a caller marker or attribute on an exported function is a compile error, not a fallback). Class and trait methods always use wrapper, except the R6 / S7 lambda frames (DotCallBuilder::null_call_attribution) and the S3 methods (CallAttribution::for_s3_method).

Source

pub fn with_call_arg(self, call_arg: bool) -> Self

Apply the call_arg option (#1834) to a resolved attribution: wrapper becomes CallAttribution::Argument. The option is validated before this runs: it is a compile error with call = caller or a CallerCall parameter (whose wrapper already takes .call), on an S3 method and on an extern "C-unwind" function, and the caller leaves the crate default out of CallAttribution::resolve when it is set, so caller never reaches here with it.

Source

pub fn dot_call_expr(self) -> &'static str

The expression the .Call() line passes as .call: the call as written, the frame it is read from on a raise, or FALSE for none.

Source

pub fn dot_call_arg(self) -> &'static str

The .call = ... argument for the .Call() line.

Source

pub fn raise_default(self) -> &'static str

The fallback call handed to .miniextendr_raise_condition: the same value as the slot, except that none passes NULL (the helper reads FALSE in the slot as “no call” and would read it here too; NULL is the plainer spelling).

Source

pub fn prelude(self, call_formal: bool) -> String

The statement the wrapper body needs before anything else: empty for CallAttribution::Wrapper, CallAttribution::NoCall and CallAttribution::Generic; the others bind .mx_call. It is the first part of the wrapper prelude, ahead of the R-side checks (preconditions, match.arg), so that those checks can attribute their failures to the caller too (#1548). call_formal says whether the wrapper has the .call formal (CallAttribution::formal); the helper then resolves whatever the caller passed there (#1613). Under CallAttribution::Argument a NULL .call is the wrapper’s own call, read inline so that a call without .call costs one is.null() (#1834); the wrapper always has the formal there, since the option is refused on S3 methods. CallAttribution::GenericEager resolves the method frame’s call up front (#1851).

Source

pub fn formal(self) -> Option<&'static str>

The trailing formal a standalone wrapper with this attribution takes: .call = NULL for CallAttribution::Caller (#1613), so a hand-written helper between the public function and the entry point can pass on the call to report, and for CallAttribution::Argument (#1834), so an R function composing exported functions can. NULL keeps the wrapper’s default (the caller’s call, or its own); an environment names the closure owning that frame (parent.frame() from a helper, environment() from the composing function); a call object is used as is. Rust identifiers cannot start with ., so the name never collides with a parameter. The caller leaves S3 methods out.

Source

pub fn param_doc(self) -> Option<&'static str>

The generated @param text for the CallAttribution::formal. It is written as the author’s own line would be, not as a filler, so a block on a page or an inheritance source no author block documents .call for still documents it (see crate::roxygen::push_fn_param_tags).

Source

pub fn r_check_call(self) -> Option<&'static str>

The call an R-side check raised in the wrapper body should carry: .mx_call when the prelude binds it, NULL for none, the frame (environment(), which .miniextendr_arg_error resolves) for an S3 method, otherwise None (the check keeps its own attribution, which is the wrapper’s frame).

Source

pub fn match_arg_statement( self, param: &str, choices: &str, aliases: Option<&str>, attrs: &ParamAttrs, ) -> String

The R statement validating a choice parameter (match_arg / choices). choices is the R expression for the choice list: a literal c("a", "b"), or the write-time placeholder for an enum. attrs are the parameter’s own attributes, which carry several_ok and the type’s layers.

Every form is one call to a preamble helper (.miniextendr_match_arg for a scalar, .miniextendr_match_arg_several for several_ok, #1472), guarded by the layers of the parameter type: !missing(..) for Missing<..> (#1551), with !identical(.., <choices>) for a single choice, whose formal reads as omitted (#2152; the .Call() argument forwards the sentinel for it, see RArgumentBuilder::with_absent_formals), then !is.null(..) for Option<..> (#1473), or is.character(..) || is.factor(..) for Either<T, R> and Either<Vec<T>, R> (#1612), which leaves NULL out too: Rust reads it as None under Option, and otherwise converts it to the R arm, even for several_ok, whose plain form reads NULL as every choice. The helpers name the argument in their messages, read a factor as its labels, and attribute the error to the wrapper’s own call by default; under CallAttribution::Caller the statement passes .mx_call so the caller is named instead (#1548), and under CallAttribution::Argument so that the call passed as .call is. The list is spelled out because the helpers, unlike base::match.arg(param), do not read it off the formal.

aliases is the match_arg parameter’s write-time match_arg_keys::aliases_placeholder, written last as , <placeholder>: the wrapper writer turns it into the type’s aliases = argument, or removes it for a type without aliases (#1843). None for a literal choices(...) list, which has no aliases.

Trait Implementations§

Source§

impl Clone for CallAttribution

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for CallAttribution

Source§

impl Debug for CallAttribution

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CallAttribution

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for CallAttribution

1.0.0 (const: unstable) · Source§

#[doc(hidden)]
fn assert_receiver_is_total_eq(&self)

👎Deprecated since 1.95.0:

implementation detail of #[derive(Eq)]

Source§

#[doc(hidden)]
fn assert_fields_are_eq(&self)

🔬This is a nightly-only experimental API. (derive_eq_internals)
Source§

impl PartialEq for CallAttribution

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for CallAttribution

Source§

impl TrivialClone for CallAttribution

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Printable for T
where T: Copy + Debug,

Source§

impl<T> SizeHint for T
where T: ?Sized,

Source§

default fn lower_bound(&self) -> usize

🔬This is a nightly-only experimental API. (core_io_internals)
Returns a lower bound on the number of elements this container-like item contains. For example, an array [u8; 12] could return any value between 0 and 12 inclusively as a correct implementation. Read more
Source§

default fn upper_bound(&self) -> Option<usize>

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an upper bound on the number of elements this container-like item contains if it can be determined, otherwise None. Read more
Source§

final fn size_hint(&self) -> (usize, Option<usize>)

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an estimate for the number of elements this container like type contains. Read more
Source§

impl<T> SizedTypeProperties for T

Source§

#[doc(hidden)]
const SIZE: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGNMENT: Alignment = _

🔬This is a nightly-only experimental API. (ptr_alignment_type)
Source§

#[doc(hidden)]
const IS_ZST: bool = _

🔬This is a nightly-only experimental API. (sized_type_properties)
true if this type requires no storage. false if its size is greater than zero. Read more
Source§

#[doc(hidden)]
const LAYOUT: Layout = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const MAX_SLICE_LEN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
The largest safe length for a [Self]. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 1 byte

Size for each variant:

  • Wrapper: 0 bytes
  • Caller: 0 bytes
  • Argument: 0 bytes
  • NoCall: 0 bytes
  • Generic: 0 bytes
  • GenericEager: 0 bytes