Expand description
Calls to base functions that a formal of the same name would shadow.
Generated R wrappers call base functions by their bare names: the
precondition guards call isTRUE() and length(), a choice formal’s
default is c("a", "b"), a Missing<T> argument is forwarded as
if (missing(x)) quote(expr=) else x, the check after .Call() calls
inherits() and attr(), and dots are forwarded as list(...) (or, for
LazyDots, the frame as environment()). R looks
up the name of a called function starting in the wrapper’s own frame, so a
formal with the same name comes first: forcing it fails when the argument
was omitted, and a function passed there is called in place of the base
function.
The rule: inside a generated wrapper, a call to one of these base functions
always means the base function, even when a formal has that name.
qualify_shadowed_calls writes base::length(...) for each call whose
name is also a formal of the wrapper, and leaves every other call alone. It
runs where every wrapper is finalized
(r_wrapper_raw_literal), so no emitter
can leave it out, and the author R code spliced into a wrapper (r_entry,
r_on_exit, r_post_checks, parameter defaults) is qualified the same way.
A formal is a Rust parameter name without its leading underscores and
without r#, unless the parameter declares its R name with formal
(#1842). A Rust identifier cannot contain ., so only a declared formal can
be named is.character, match.call or .Call: dotted base callees are
listed and qualified like the others. A declared formal can’t take a name
of the framework’s own (.miniextendr_arg_error, .mx_self, .call,
.Generic; r_wrapper_builder::declared_formal_problem), so the calls to
those are never qualified.
Only the colliding calls are qualified because :: costs time on every
call: the byte compiler compiles base::f(x) as a call to the ::
primitive instead of inlining f. On a byte-compiled one-argument wrapper,
qualifying the guards added about 200 ns per call (+19%), and qualifying
every call about 475 ns (+44%). When no formal collides, the text is
returned unchanged.
Three generators do not finalize through here: the sidecar accessors of
#[derive(ExternalPtr)], the functions #[derive(Vctrs)] emits and the
all.equal() methods of #[derive(AllEqual)]. Their formals are fixed
(x, value, to, target, current, tolerance, scale, …), and
none of their bodies calls a function of one of those names.
Constants§
- BASE_
CALLEES 🔒 - The base functions that generated wrapper text calls by their bare names.
Functions§
- formal_
names 🔒 - The R formals of every wrapper built from
signatures, each a parameter list with the formals it declares: the union of each signature’sr_formal_names. - ident_
end 🔒 - End of the identifier (or number) starting at
start. - identifiers 🔒
- Byte ranges of the R identifiers in
text, skipping strings ("...",'...'), raw strings (r"(...)",R'[...]',r"-{...}-"), comments, backtick names,%op%operators and numbers. - infix_
end 🔒 - End of the
%op%operator starting atstart, or just past the%when the line has no closing%. - is_
accessed 🔒 - Whether the identifier starting at
startfollows::,:::,$or@, so it names a namespace export or a member, not a function in scope. - is_call 🔒
- Whether the identifier ending at
endis called: followed by optional spaces and(. - qualify_
shadowed_ 🔒calls - Write
base::before every call intextto aBASE_CALLEESfunction that shares its name with one offormals. - quoted_
end 🔒 - End of the string or backtick name opened by
quoteatstart, after its closing quote. A backslash escapes the next character. - raw_
string_ 🔒end - End of the raw string whose quote is at
quote_at, right after anrorR: the quote, any dashes, and an opening(,[or{, closed by the matching bracket, the same dashes and the same quote.Nonewhen the quote does not open a raw string.