Expand description
R-side precondition generation for type checking.
Generates argument checks in R wrapper functions that run BEFORE the .Call() boundary.
This gives users clear, idiomatic R error messages with proper stack traces instead of
Rust panic messages.
Each check tests ONE thing and names the requirement it enforces:
add <- function(a, b) {
if (!isTRUE(is.integer(a))) .miniextendr_arg_error("a", "must be integer")
if (!isTRUE(length(a) == 1L)) .miniextendr_arg_error("a", "must have length 1")
if (!isTRUE(is.integer(b))) .miniextendr_arg_error("b", "must be integer")
if (!isTRUE(length(b) == 1L)) .miniextendr_arg_error("b", "must have length 1")
.Call(C_add, .call = sys.call(), a, b)
}A failing check calls the preamble helper .miniextendr_arg_error
(miniextendr-api/src/registry.rs), which raises the same condition as a
failed Rust conversion: the crate’s conversion_error_class, rust_error,
kind = "conversion" and e$param, with the message 'a' must be integer
(#1591). A passing check costs one isTRUE() test; the condition is only
built on failure. isTRUE() keeps stopifnot()’s failure semantics (NA
fails too), and the guards are cheaper than the stopifnot() call they
replace. conversion_expectation gives the Rust conversion the same
vocabulary for its messages.
Structs§
- Explicit
Checks - R-side checks the author asked for by name on one parameter, rather than ones derived from its Rust type.
- Fallback
Param - A parameter whose Rust type is not in the static type table.
- Inherits
Hint - One
when(class = "...", message = "...")hint of aninheritscheck (#1824): the message a value gets when it fails the check and inherits from one ofclasses, in place of the check’s own. Adata.framepassed where a model object is expected can be told which function takes a data frame, whileNULLor a number gets the plain refusal. - Precondition
Options - Per-function knobs that influence precondition codegen.
- Precondition
Output - Output of precondition analysis for a function’s parameters.
- RAssertion 🔒
- A single R-side check on one parameter: a requirement and the R condition enforcing it.
Enums§
- RType
Check 🔒 - Classification of an R-side type check for a function parameter.
Functions§
- build_
precondition_ checks - Build precondition checks for a function’s parameters.
- class_
list_ 🔒r - A class check’s classes in R: the quoted list for its message
(
'a', 'b' or 'c') and the argument ofinherits()("a"orc("a", "b", "c")), each class escaped as an R string. - coerce_
widened 🔒 - Keep the R gate in sync with the conversion actually selected for this type.
- conversion_
expectation 🔒 - The R-facing expectation for a parameter of Rust type
ty, for the message of its Rust conversion failure:'<p>' must be <expected>: ...(seeRTypeCheck::expectation). - extract_
single_ 🔒generic_ arg - Extract the single generic type argument from a path segment.
- guarded 🔒
- Let an
Option<T>parameter passNULL, and aMissing<T>parameter an omitted argument, in the named checksouton parameterparamof typety: each condition gains anis.null(param) ||/missing(param) ||prefix. The failure message names only the failed requirement: it is shown only for a present, non-NULLvalue. - has_
type_ 🔒check - Whether a parameter type has type-derived R-side checks at all, i.e.
whether
Checked/Uncheckedand the per-parameter keywords have anything to keep or drop (SEXP,Missing<T>,ExternalPtr<T>,&Dotsand unknown types have none). - integer_
vector_ 🔒wide_ check - Build the lossless whole-number predicate for a
REALSXP-accepting integer vector (thei64/u64/isize/usizefamily). - is_
skip_ 🔒type - Returns
truefor types that should never get a fallback precheck. - is_
vector_ 🔒valued - Whether an argument of Rust type
tyholds several values, so ano_nafailure readsmust not contain NArather thanmust not be NA. - merge_
message 🔒 - Record
fromas the message ofcheck, which may have only one. - needs_
fallback 🔒 - Returns
trueif a type is unknown to the static type table and should be recorded as a fallback parameter. - no_
na_ 🔒checked_ after_ conversion - Whether a
no_naparameter of Rust typetyis checked forNAonly in Rust, after the conversion, with no R guard: anEither<L, R>, also underMissingandOption. The layers are peeled as for a choice parameter (crate::type_inspect::choice_layers). A plainOption<Either<..>>converts throughTryFromSexp, which readsNULLasNone(noNA) and asks theEitherotherwise; a choiceOption<Either<Mode, X>>keeps the guard (see below). The type is read as written: an alias, a newtype or aResult<Either<..>, ()>keeps the guard. - no_
na_ 🔒holds_ several - Whether a
no_navalue of Rust typetyholds several values, looking through the layersno_nachecks through:Missing,Option,Result<T, _>(itsT) andEither<L, R>, which holds several when either arm does. The text is fixed at compile time, before the conversion picks an arm, andcontainalso reads right for one value. - no_
na_ 🔒message - The condition message of a failed
no_nacheck on parameterparamof typety: the author’sno_na(message = "...")verbatim (custom), else'<param>' must not be NA/'<param>' must not contain NA(no_na_requirement). The R guard builds the same text in R (.miniextendr_arg_error); the C wrapper’s post-conversion check passes this one toarg_check_condition_value. - no_
na_ 🔒requirement - What a
no_naparameter of Rust typetymust satisfy, without the parameter name:must not contain NAfor a value holding several values (no_na_holds_several), elsemust not be NA. - numeric_
or_ 🔒text_ check - Build the predicate for the
AsNumeric/AsNumericVecmarkers. - numeric_
type_ 🔒check - Build the R expression for the numeric type predicate.
- r_
check_ 🔒for_ reference - Map a reference type to its R-side type check.
- r_
check_ 🔒for_ type - Map a Rust type to its R-side type check, if applicable.
- r_
check_ 🔒for_ type_ path - Map a
syn::TypePathto its R-side type check. - r_
check_ 🔒for_ vec_ element - Map a
Vec<T>or&[T]element type to the appropriate vector type check. - resolve_
item_ 🔒type_ checks resolve_type_checkswithout a per-parameter spelling: whether an item (function or method) keeps its type-derived checks by default, ranks 2 to 6. The condition-raise codegen keys on this item-level decision.- resolve_
type_ 🔒checks - Whether one parameter keeps its type-derived R-side checks, from every spelling that can decide it, most specific first; the first that speaks wins:
- strict_
conversion_ 🔒expectation - The R-facing expectation of a
strictlossy-integer parameter (i64,u64,isize,usizeand theirVec/Vec<Option<_>>forms), whose Rust conversion accepts only integer and whole-number double input (#1594):a single whole number/a single non-negative whole numberfor a scalar, the vector’s usualinteger or whole-number numericotherwise. - unchecked_
expectation 🔒 - The R-facing expectation of a type that has no R-side check, so its conversion alone says what it accepts (#1594):
- unchecked_
params 🔒 - The R formals (
formals) of the parameters ofinputswhose type-derived checks are dropped, given each one’s rank-1 decision (param, keyed by Rust name) and the item, impl and crate defaults (resolve_type_checks; the feature is this macro crate’sno-preconditions-default).