pub(crate) unsafe fn raise_rust_condition_via_stop(
tagged_value: impl FnOnce() -> SEXP,
call: Option<SEXP>,
) -> !Expand description
Raise the R condition for a tagged condition value by evaluating the
shared .miniextendr_raise_condition helper on it, the helper every
generated R wrapper calls on the value its .Call() returns.
This is Approach 3 from the issue-345 plan: an Rf_eval that ends in
stop(structure(...)), for contexts with no outer R wrapper to inspect a
tagged SEXP. It is the only viable option for ALTREP callbacks, which are
invoked directly by R’s runtime (no .Call frame, no R wrapper).
tagged_value builds the value (with crate::error_value’s
constructors). Because the helper raises it, the condition is the one the
wrapper raises for the same value, field for field (#1768): message,
call, kind, then the data = fields spliced with utils::modifyList,
so a data field named message, call or kind replaces the base field
on both transports (#1315); the classes ahead of the rust_* layering.
The copy evaluated here lives in the base namespace, so the caller
resolves arg_error!’s class marker in Rust first.
The value must be of an error kind (stop() longjmps, so this function
never returns); the helper’s warning / message / condition arms return.
§Nothing Rust-owned survives the longjmp
The longjmp skips every Rust frame above R’s, so no destructor runs past
this point. tagged_value consumes what it captures (message, classes,
data) and is itself dropped before Rf_eval; the SEXPs are rooted with
plain Rf_protect, whose stack R resets on the jump, rather than a
drop guard that would never run.
§MXL300 compliance
This function raises an R error via Rf_eval(stop(...)), not via direct
Rf_error/Rf_errorcall. MXL300 does not flag Rf_eval.
§Safety
Must be called from R’s main thread in a context where R longjmps are
safe, with no Rust value that needs dropping left on the caller’s frames.
In practice, always called from with_r_unwind_protect_sourced (ALTREP
RUnwind guards, with_r_unwind_protect_or_raise) after its guarded
closure has returned.