--- src/inspect.cpp 2023-01-17 23:07:57.000000000 +0800 +++ src/inspect.cpp 2026-07-06 06:46:08.000000000 +0800 @@ -2,7 +2,9 @@ using namespace Rcpp; bool is_namespace(Environment env) { - return Rf_findVarInFrame3(env, Rf_install(".__NAMESPACE__."), FALSE) != R_UnboundValue; + // R_IsNamespaceEnv is public API in R >= 2.7.0; replaces the manual + // Rf_findVarInFrame3(env, ".__NAMESPACE__.", ...) check. + return (bool) R_IsNamespaceEnv(env); } std::string sexp_type(SEXP x); @@ -17,10 +19,10 @@ List inspect_rec(SEXP x, Environment base_env, std::set& seen) { // If we've seen it before, return nothing if (!seen.insert(x).second) { - List out = List::create( + List out = List::create( _["address"] = address(x), _["type"] = sexp_type(x), - _["named"] = NAMED(x), + _["shared"] = (bool) MAYBE_SHARED(x), _["seen"] = true ); std::vector klass; @@ -69,9 +71,9 @@ case LANGSXP: case BCODESXP: children = List::create( - _["tag"] = inspect_rec(TAG(x), base_env, seen), // name of first element - _["car"] = inspect_rec(CAR(x), base_env, seen), // first element - _["cdr"] = inspect_rec(CDR(x), base_env, seen) // pairlist (subsequent elements) or NILSXP + _["tag"] = inspect_rec(TAG(x), base_env, seen), + _["car"] = inspect_rec(CAR(x), base_env, seen), + _["cdr"] = inspect_rec(CDR(x), base_env, seen) ); break; @@ -80,34 +82,32 @@ if (x == R_BaseEnv || x == R_GlobalEnv || x == R_EmptyEnv || x == base_env || is_namespace(x)) break; + // FRAME() and HASHTAB() have no public replacements in R >= 4.6.0. + // R_ParentEnv() replaces ENCLOS(). children = List::create( - _["frame"] = inspect_rec(FRAME(x), base_env, seen), - _["enclos"] = inspect_rec(ENCLOS(x), base_env, seen), - _["hashtab"] = inspect_rec(HASHTAB(x), base_env, seen) + _["enclos"] = inspect_rec(R_ParentEnv(x), base_env, seen) ); break; - // Functions + // Functions — R_ClosureFormals/Body/Env replace FORMALS/BODY/CLOENV case CLOSXP: children = List::create( - _["formals"] = inspect_rec(FORMALS(x), base_env, seen), - _["body"] = inspect_rec(BODY(x), base_env, seen), - _["env"] = inspect_rec(CLOENV(x), base_env, seen) + _["formals"] = inspect_rec(R_ClosureFormals(x), base_env, seen), + _["body"] = inspect_rec(R_ClosureBody(x), base_env, seen), + _["env"] = inspect_rec(R_ClosureEnv(x), base_env, seen) ); break; + // Promises — no public replacement for PRCODE/PRENV in R >= 4.6.0. + // R_PromiseExpr() (= old PRCODE) is available only under + // ENABLE_LEGACY_NONAPI_FUNS; omit those children. case PROMSXP: - children = List::create( - _["value"] = inspect_rec(PRVALUE(x), base_env, seen), - _["code"] = inspect_rec(PRCODE(x), base_env, seen), - _["env"] = inspect_rec(PRENV(x), base_env, seen) - ); break; case EXTPTRSXP: children = List::create( - _["prot"] = inspect_rec(EXTPTR_PROT(x), base_env, seen), - _["tag"] = inspect_rec(EXTPTR_TAG(x), base_env, seen) + _["prot"] = inspect_rec(R_ExternalPtrProtected(x), base_env, seen), + _["tag"] = inspect_rec(R_ExternalPtrTag(x), base_env, seen) ); break; @@ -125,13 +125,15 @@ List out = List::create( _["address"] = address(x), - _["type"] = sexp_type(x), - _["named"] = NAMED(x), - _["seen"] = false + _["type"] = sexp_type(x), + _["shared"] = (bool) MAYBE_SHARED(x), + _["seen"] = false ); - if (ATTRIB(x) != R_NilValue) { - children["attributes"] = inspect_rec(ATTRIB(x), base_env, seen); + // R_getAttributes() returns the full attribute pairlist, replacing ATTRIB(). + SEXP attrs = R_getAttributes(x); + if (attrs != R_NilValue) { + children["attributes"] = inspect_rec(attrs, base_env, seen); } if (children.size() > 0) { out["children"] = children; @@ -148,14 +150,14 @@ // [[Rcpp::export]] List inspect_(SEXP x, Environment base_env) { std::set seen; - return inspect_rec(x, base_env, seen); } // [[Rcpp::export]] std::string address2(Symbol name, Environment env) { - SEXP object = Rf_findVar(name, env); + // R_getVar(sym, env, inherits) replaces Rf_findVar(sym, env) + SEXP object = R_getVar(name, env, TRUE); std::ostringstream s; s << object; return s.str(); @@ -163,6 +165,6 @@ // [[Rcpp::export]] int named2(Symbol name, Environment env) { - SEXP object = Rf_findVar(name, env); - return NAMED(object); + SEXP object = R_getVar(name, env, TRUE); + return (int) MAYBE_SHARED(object); } --- src/promise.cpp 2023-01-17 23:07:57.000000000 +0800 +++ src/promise.cpp 2026-07-06 07:00:14.000000000 +0800 @@ -1,31 +1,38 @@ +#define ENABLE_LEGACY_NONAPI_FUNS #include using namespace Rcpp; // [[Rcpp::export]] bool is_promise2(Symbol name, Environment env) { - SEXP object = Rf_findVar(name, env); - - return (TYPEOF (object) == PROMSXP); + SEXP object = R_getVar(name, env, FALSE); + return (TYPEOF(object) == PROMSXP); } // [[Rcpp::export]] SEXP promise_code(Symbol name, Environment env) { - SEXP object = Rf_findVar(name, env); - return PRCODE(object); + SEXP object = R_getVar(name, env, FALSE); + return R_PromiseExpr(object); } + // [[Rcpp::export]] SEXP promise_value(Symbol name, Environment env) { - SEXP object = Rf_findVar(name, env); - return PRVALUE(object); + // PRVALUE has no public replacement in R >= 4.6.0. + // R_BindingTypeForced means the promise has been evaluated; + // R_getVarEx with wantActive=FALSE returns the forced value. + if (R_GetBindingType(name, env) == R_BindingTypeForced) { + return R_getVarEx(name, env, FALSE, R_NilValue); + } + return R_UnboundValue; } + // [[Rcpp::export]] bool promise_evaled(Symbol name, Environment env) { - SEXP object = Rf_findVar(name, env); - return PRVALUE(object) != R_UnboundValue; + return R_GetBindingType(name, env) == R_BindingTypeForced; } + // [[Rcpp::export]] SEXP promise_env(Symbol name, Environment env) { - SEXP object = Rf_findVar(name, env); + SEXP object = R_getVar(name, env, FALSE); return PRENV(object); } @@ -37,13 +44,13 @@ } // recurse until we find the real promise, not a promise of a promise - while(true) { - SEXP code = PRCODE(prom); - if(TYPEOF(code) != PROMSXP) break; + while (true) { + SEXP code = R_PromiseExpr(prom); + if (TYPEOF(code) != PROMSXP) break; prom = code; } - SEXP args = PROTECT(Rf_lcons(PRCODE(prom), R_NilValue)); + SEXP args = PROTECT(Rf_lcons(R_PromiseExpr(prom), R_NilValue)); RObject formula = Rf_lcons(Rf_install("~"), args); UNPROTECT(1); @@ -55,7 +62,7 @@ // [[Rcpp::export]] RObject explicitPromise(Symbol name, Environment env) { - SEXP prom = Rf_findVar(name, env); + SEXP prom = R_getVar(name, env, FALSE); return makeExplicit(prom); } @@ -69,17 +76,16 @@ dots = env.find("..."); SEXP el; - for(SEXP nxt = dots; nxt != R_NilValue; el = CAR(nxt), nxt = CDR(nxt)) { + for (SEXP nxt = dots; nxt != R_NilValue; el = CAR(nxt), nxt = CDR(nxt)) { out.push_back(makeExplicit(el)); - SEXP name = TAG(nxt); - if (Rf_isNull(name)) { + SEXP tag = TAG(nxt); + if (Rf_isNull(tag)) { names.push_back(""); } else { names.push_back(""); } } - return out; } --- src/typename.cpp 2023-01-17 23:07:57.000000000 +0800 +++ src/typename.cpp 2026-07-06 07:04:44.000000000 +0800 @@ -54,6 +54,6 @@ // [[Rcpp::export]] std::string typename2(Symbol name, Environment env) { - SEXP object = Rf_findVar(name, env); + SEXP object = R_getVar(name, env, FALSE); return sexp_type(object); }