Expand description
Function signature parsing for #[miniextendr].
This module handles parsing and normalizing Rust function signatures for the
#[miniextendr] attribute macro. It provides:
MiniextendrFunctionParsed: Parsed function with normalization and codegen helpersMiniextendrFnAttrs: Parsed#[miniextendr(...)]attribute optionsCoercionMapping: Type coercion analysis for automatic R→Rust conversion
Structs§
- Miniextendr
FnAttrs 🔒 - Parsed arguments for the
#[miniextendr(...)]attribute on functions. - Miniextendr
Function 🔒Parsed - Parsed + normalized Rust function item for
#[miniextendr]. - Param
Attrs 🔒 - Collapsed per-parameter attribute state for a single function parameter.
- PerParam
Miniextendr 🔒Attr - Parsed per-parameter
#[miniextendr(...)]attribute content. - ROnExit 🔒
- Parsed
r_on_exitattribute foron.exit()cleanup code in R wrappers. - Rename
Pair 🔒 - One
from = "to"entry ofrename(...).fromis an identifier or, for a serde-renamed field whose name is not one, a string literal. - Serde
Error 🔒Spec #[miniextendr(serde_error)]: derive theErrarm’s condition class and data from the error type’sserde::Serializeoutput instead of theRConditionData/Debugprobe.
Enums§
- Class
Check 🔒 - The two class checks a parameter can name:
inherits(the argument must inherit from one of the classes) andnot_inherits(from none of them, #1815). Both take the same spellings at parameter and method level; this says which one a spelling is, and words its errors. - Coercion
Mapping 🔒 - Conversion selected by
coerce, shared by Rust conversion and R checks. - Dots
Kind 🔒 - Which
...parameter type a parameter takes. - Field
Type 🔒 - The R type an
as_*option gives a payload field. - Return
Pref 🔒 - Preferred return-conversion path for
IntoR.
Constants§
- FN_
BOOL_ 🔒FLAGS_ HELP - Comma-separated list of all fn-level boolean flags, for error messages.
- FN_
NESTED_ 🔒OPTIONS_ HELP - Comma-separated list of fn-level nested options, for error messages.
- FORMAL_
NOT_ 🔒STRING - The error of a
formalwhose value is no string literal (#1842). - FORMAL_
TWICE 🔒 - The error of a second
formalon one parameter (#1842). - MISSING_
DEFAULT_ 🔒PARAM_ DOC - The generated
@paramtext of an undocumentedMissing<..>parameter with a formal default (#2161): the default only shows in the usage line, and an omitted argument still reaches Rust asMissing::Absent. - RESERVED_
CONDITION_ 🔒FIELDS - The condition’s own slots, mirrored from
miniextendr_api::condition::RESERVED_CONDITION_FIELDS(the macros crate cannot depend on the API crate). The runtime check remains the backstop. - SERDE_
ERROR_ 🔒BARE_ HELP - The bare flag / boolean forms: the serde path is not something to switch on per function.
- SERDE_
ERROR_ 🔒OPTIONS_ HELP - SERDE_
ERROR_ 🔒SHAPE_ HELP - TRAIT_
FORMAL_ 🔒UNSUPPORTED - The error of a
formal(...)on a trait method (#1842), declared or implemented. A trait method’s R formals are its declaration’s parameter names, shared by every implementing type and the trait ABI’s metadata; declared formals cover standalone functions and inherent impl methods. - WHEN_
ON_ 🔒NOT_ INHERITS - The error for
when(...)innot_inherits(...).
Functions§
- absent_
formals_ 🔒by_ r_ name - The parameters of
per_param(keyed by Rust name) whose wrapper reads a valueidentical()to the formal as omitted (ParamAttrs::absent_formal, #2152), as R formal → the formal’s default: thematch_argplaceholder keyed by the C wrapperc_ident, or the literalchoices(...)vector. Forcrate::r_wrapper_builder::RArgumentBuilder::with_absent_formals. - both 🔒
- A field named by two options that exclude each other.
- check_
lazy_ 🔒dots_ params - Check the
LazyDotsparameters of a signature (#1892):LazyDotsis the parameter’s whole type, taken by value (&LazyDots,Option<LazyDots>,Vec<LazyDots>are refused;Missing<LazyDots>is refused byvalidate_param_type), and no per-parameter option names it (has_options, keyed by Rust name): the wrapper passes its frame, and every option would force the dots or has nothing to act on. - check_
nargs_ 🔒params - Check the
NArgsparameters of a signature (#1860): at most one, and none that a per-parameter option names (has_options, keyed by Rust name). The parameter is no R argument (the wrapper fills it withnargs()), so an option would have nothing to act on. - check_
param_ 🔒preconditions - Reject a parameter’s rank-1 precondition decision where it has nothing to
act on: a
match_arg/choicesparameter (validated bymatch.arg(), never by type checks) and a type without type-derived checks (SEXP,Missing<T>,ExternalPtr<T>,&Dots, a type the check table does not know).tyis the parameter’s type with the markers peeled, which the errors point at;markersare the ones it carried. A no-op when the parameter decides nothing itself. - check_
replacement_ 🔒value_ param - Check that an S3 method for a replacement generic takes the new value last,
as
value. - check_
rng_ 🔒guard_ params - Check the RNG guard parameters of a signature (#2002):
&RngGuardis filled by a#[miniextendr(rng)]wrapper (rng) with the guard it holds, so it needsrng, takes no per-parameter option (has_options, keyed by Rust name: it is no R argument) and appears at most once. Any other shape that namesRngGuard(&mut RngGuard, by value, inside another type) is refused: the wrapper lends its guard for the call. - check_
rng_ 🔒seed - Check
rng(seed = <param>)(#2198) against a standalone function’s signature and return the seed’s R formal. Every problem is reported at once: - choice_
alternatives_ 🔒suffix - The other values a choice parameter accepts, after its quoted choices:
, or a data framefor anEither<.., R>layer (noun, theRarm),, or <null_word>for anOption<..>layer (optional),, a data frame, or <null_word>for both, nothing for neither. Shared by the parameter’s@paramline (ParamAttrs::choice_doc_suffix, which passesNULL for no choice) and the argument error of anEitherchoice parameter (which passesNULL), so the two word the alternatives alike. - classify_
choice_ 🔒param - Record the layers of a
match_arg/choicesparameter’s type on itsParamAttrs(optional,omittable,either_noun) and reject the shapes the codegen cannot serve, now that the type is known. Shared by the standalone-fn parser andfinalize_method_param_attrsso the two cannot classify a type differently. A no-op for other parameters. - collect_
param_ 🔒markers - The markers of every parameter of
inputsthat carries one, keyed by Rust name, in signature order. Nested or stacked markers are an error (seecrate::type_inspect::peel_param_markers). - default_
serde_ 🔒error_ prefix - Default family class for
serde_error:<crate>_error, from the crate being compiled (cargo setsCARGO_CRATE_NAMEfor the rustc invocation that runs this proc macro). - dots_
formal_ 🔒error - The error of a
formalon the dots parameter (#1842), at the literal. - dots_
index 🔒 - Position of the first
...parameter (&DotsorLazyDots) ininputs(receiver included, asRArgumentBuildercounts them), without validation: for code that runs afterfind_dots_paramhas accepted the signature. - dots_
kind 🔒 - The
...parameter typetyis, if any:Dots/&Dots(DotsKind::Forced), orLazyDotstaken by value (DotsKind::Lazy,crate::type_inspect::is_lazy_dots_marker).&LazyDotsand other shapes are none; the callers refuse them by name. - explicit_
checks_ 🔒by_ r_ name - The non-empty
ParamAttrs::checksofper_param(keyed by Rust name), re-keyed by R formal (crate::r_wrapper_builder::Formals::of) forcrate::r_preconditions::PreconditionOptions::explicit. - field_
names 🔒 - The non-empty string literals of
skip(..)/as_*(..); problems go toerrors. - finalize_
method_ 🔒param_ attrs - Check an impl or trait method’s per-parameter attributes against its
signature, now that it is known. Every parameter a method-level
match_arg(...)/choices(...)/no_default(...)/inherits(...)/not_inherits(...)/no_na(...)/preconditions(...)/no_preconditions(...)/formal(...)names must exist (a typo would otherwise drop the option without a word); then aformalis refused on the&Dotsparameter, whose formal is..., ano_default(p)on a parameter that is no choice or has a default (no_default_conflict), the choice parameters are classified (seeclassify_choice_param), a class in bothinheritsandnot_inheritsis refused (crate::r_preconditions::ExplicitChecks::class_conflict), and each parameter’s own precondition decision is checked (check_param_preconditions). The standalone-fn path does the same while parsing; this is the twin for method-level attributes, whose parameter names arrive before the types. The inherent-impl and trait-impl parsers both call it, so they reject an unknown name the same way.inputshas the parameter markers peeled;markersare the ones peeled (empty on a trait impl, whose signature is the trait’s).spanis where the errors point: the first such attribute, else the method name. - find_
dots_ 🔒param - Find the dots parameter of a signature by type, at any position, and return its Rust binding.
- get_
missing_ 🔒inner_ type - Extract the inner type
TfromMissing<T>, if the type isMissing<T>. - hint_
class 🔒 - One class name of a parameter-level
when(...)hint: not empty. - inherits_
hint 🔒 - A parsed
when(...)hint, which needs both its classes and its message. - init_
marker_ 🔒ident - The marker type
miniextendr_init!defines at the crate root. Aserde_error_shape!declaration is an impl keyed by it, which is what lets a crate declare a shape for an error type from another crate (#2207). - init_
marker_ 🔒path crate::__MiniextendrInitMarker, as the generatedErrarms pass it to the API’s probe macros. Those resolve it only under the API’sserdefeature, where a shape can be declared.- is_
dots_ 🔒type - Check if a type is a
...parameter type:Dots/&DotsorLazyDots(seedots_kind). - is_
missing_ 🔒type - Check if a type is
Missing<T>. - is_
vector_ 🔒like_ type - Check if a type is a vector-like type that
several_okcan populate. - merge_
param_ 🔒policy - Combine a parameter’s
Checked<T>/Unchecked<T>marker with its keyword decision (keyword: the per-parameterpreconditions/no_preconditions, or the method’spreconditions(p)/no_preconditions(p)). A marker is a type, not one more flag of the pair, so a marker and a keyword that disagree are an error, as aCallmarker andcall = ...are; agreeing ones are one decision. The error points atty, the parameter’s type as written. - method_
check_ 🔒param - The parameter an entry of a method-level
match_arg(...)/choices(...)/no_na(...)/inherits(...)/not_inherits(...)names, spelled as the signature’scrate::naming::ident_name(r#typenamestype), sofinalize_method_param_attrsfinds it. - method_
class_ 🔒list - The classes of a method-level
inherits/not_inheritsentry: a comma-separated, non-empty list. - missing_
choice_ 🔒default_ msg - A
defaulton a choice parameter underMissing<..>(#2161). An omitted argument reaches Rust asMissing::Absent, so the default would pick no choice; on achoices(...)list it would also replace the formal, the choice vector thatParamAttrs::absent_formalcompares a supplied value with (#2152). - missing_
default_ 🔒param_ docs - R formal →
MISSING_DEFAULT_PARAM_DOCfor eachMissing<..>parameter ofinputsthat has a formal default indefaults(keyed by Rust name, as the per-parameter options are) and is no choice parameter ofper_param, whose own line names the choices. The key is the formalformalsgives the parameter, a declaredformalincluded (#1842).Missing<Quoted>/Missing<Quosure>count too: their default is never evaluated either. - no_
default_ 🔒conflict - The error of a
no_defaultthat cannot apply (#1828), orNone: on a parameter that is neithermatch_argnorchoices(only a choice parameter gets a generated default to drop), or together with a default.method_listpicks the spellings named: the method-levelno_default(p)/defaults(p = ...), else the parameter’s ownno_default/default = "...". - non_
empty_ 🔒lit_ str - A
tag = "..."/prefix = "..."value: a non-empty string literal. - optional_
choice_ 🔒default_ msg - parse_
class_ 🔒check_ list inherits(...)/not_inherits(...)on a parameter (checksays which): each string literal, and eachclass = "...", names one class (the argument must inherit from one of them, or from none of them);message = "..."gives the condition message of a failure, for all of them. No string is split on commas, as withinherits = "cls"(the method-levelclass = "a, b"is split, seeparse_method_class_check).- parse_
lit_ 🔒str - parse_
method_ 🔒class_ check - Method-level
inherits(p = "a, b", q(class = "a, b", message = "..."))/not_inherits(...)(the same shape,checksays which) on an impl or trait method: each entry names a parameter and the classes it must inherit from (one of) or must not inherit from (any of), optionally with the condition message of the class check. A nested value cannot be a bare list of literals, so the classes are one comma-separated string, as inchoices(p = "a, b").inherits(q(class = "a", when(class = "b, c", message = "...")))adds a hint (#1824;parse_method_when). Shared by the inherent-impl and trait-impl method parsers. - parse_
method_ 🔒formal - Parse a method-level
formal(conf_int = "conf.int", ...)(#1842): the R formal of each named parameter, the method form of a standalone function’s per-parameterformal = "..". Shared by the inherent-impl parser only: trait methods take their formals from the trait declaration, and the trait parsers refuse it. A parameter named twice is an error;finalize_method_param_attrsrefuses a name that is no parameter, andcrate::r_wrapper_builder::check_r_formalschecks each formal. - parse_
method_ 🔒no_ default - Method-level
no_default(p, q)on an impl or trait method, whose parameters cannot carry attributes: each entry names amatch_arg/choicesparameter whose R formal has no default (#1828). Shared by the inherent-impl and trait-impl method parsers;finalize_method_param_attrsrefuses a name that is no parameter, no choice or has a default. - parse_
method_ 🔒no_ na - Method-level
no_na(p, q(message = "..."))on an impl or trait method, whose parameters cannot carry attributes: each entry names a parameter, optionally with the condition message of its NA check. Shared by the inherent-impl and trait-impl method parsers. - parse_
method_ 🔒preconditions - Method-level
preconditions(p, q)/no_preconditions(p)on an impl or trait method, whose parameters cannot carry attributes: each entry names a parameter that keeps (keep) or drops its type-derived R-side checks. Naming one parameter twice follows the pair rule: the last one written wins. Shared by the inherent-impl and trait-impl method parsers; the barepreconditions/no_preconditions(the whole method) is theirs to read. - parse_
method_ 🔒when - A method-level
when(class = "a, b", message = "...")hint ininherits(p(...)): its classes are one comma-separated string, as the entry’s ownclass, and its message is required. - parse_
no_ 🔒na_ list no_na(message = "...")on a parameter:no_nawith the condition message of a failure.- parse_
no_ 🔒na_ option - One option inside
no_na(...)(parameter level) orno_na(p(...))(method level): onlymessage = "...". - parse_
per_ 🔒param_ attr - Parse all per-parameter options from a
#[miniextendr(...)]attribute. - parse_
rng_ 🔒seed - Parse
rng(seed = <param>)(#2198): the parameter, by its Rust name, whose value the wrapper passes toset.seed(). - parse_
serde_ 🔒error_ list - Parse
serde_error(shape = .., tag = "...", prefix = "...", skip(...), rename(...), as_*(...))given as aMeta::List. - parse_
serde_ 🔒error_ nested - Parse the tail of a
serde_erroroption insideparse_nested_meta. Only the option list(shape = .., tag = "...", skip(...), as_character(...), ...)is accepted; the bare flag and= true/falseare rejected withSERDE_ERROR_BARE_HELP, since the serde path is on for every eligible error type under theserdefeature. - parse_
when_ 🔒list - The content of a parameter-level
when(...)hint ininherits(...)(keyis thewhenkeyword, for error spans): its classes, spelled as ininherits(...)(each string literal and eachclass = "..."names one class, none split on commas), and its requiredmessage = "...". - peeled_
inputs 🔒 inputswith each marked parameter’s type replaced by the type under its markers (markers, keyed by Rust name): what every R-side consumer and the conversion see. The item re-emitted for the user keeps the markers.- per_
param_ 🔒in_ signature_ order - The entries of
per_paramin the order their parameters appear ininputs. Code that emits one line or item per parameter walks this, never the map itself: aHashMap’s order differs between maps and between compiler runs, so the generated R wrapper (and the Rust items) would too. - preconditions_
keyword 🔒 - The keyword spelling of a rank-1 precondition decision, for messages: the per-parameter attribute on a function parameter, the method-level list on a method.
- refuse_
lazy_ 🔒dots_ in_ trait_ method - Refuse a
LazyDotsparameter on a trait method (#1892), in any shape: the trait declaration (#[miniextendr_trait]) and a trait impl. A trait method’s arguments cross the vtable as values its shim converts withTryFromSexp, as for&Dots, which trait methods don’t take either;LazyDotsis the generated wrapper’s frame, which has no such value. - refuse_
rng_ 🔒guard_ in_ trait_ method - Refuse an
RngGuardparameter on a trait method (#2002), in any shape: the trait declaration and a trait impl. A trait method’s arguments cross the vtable as values its shim converts withTryFromSexp, and the guard is no R value. - refuse_
rng_ 🔒seed_ on_ method - Refuse
rng(seed = ..)on an impl or trait method (#2198), spanned on the option: the seed contract is written in the R wrapper of a standalone function or ans3(...)method.metaisrng, followed by its parenthesized options. - rewrite_
variadic_ 🔒dots - Replace Rust variadic syntax (
name: .../_: ...) with a trailing&miniextendr_api::dots::Dotsparameter, so downstream codegen never emits a non-extern variadic Rust fn. Named dots keep the user’s identifier;_: ...binds__miniextendr_dots. - set_
check_ 🔒message - Record the
message = "..."of aninherits/not_inherits/no_nacheck: the condition message of a failure, used verbatim. It is given once, is not empty, and holds no NUL (an R string cannot). - set_
hint_ 🔒message - Record the
message = "..."of awhen(...)hint ininherits(...), under the rules ofset_check_message; unlike a check’s message, the hint’s is required. - set_
message 🔒 - Record
valueas the message inslotofcheck(...);if_emptyends the error for an empty message. - type_
ends_ 🔒with - Check if a type path ends with the given identifier (e.g., “Dots”, “Missing”).
- typed_
list_ 🔒on_ lazy_ dots - The error for
dots = typed_list!(..)on a function whose...is aLazyDotsparameter (#1892):typed_list!validates the forcedlist(...)of a&Dotsparameter, andLazyDotsforces nothing.Nonewhen the dots are&Dots(or absent).spanis the attribute’s, else the parameter’s. - validate_
param_ 🔒type - Validate a parameter’s type for
MissingandDotsconflicts. - validate_
per_ 🔒param_ attr_ conflicts - Validate per-parameter attribute conflicts.
- validate_
postfix 🔒 - Parse the value of a
name = "..."meta item as a string literal.