Skip to content

Add backports module for R 4.5 C-API compliance#265

Open
CGMossa wants to merge 1 commit into
extendr:masterfrom
CGMossa:copy-extendr-backports
Open

Add backports module for R 4.5 C-API compliance#265
CGMossa wants to merge 1 commit into
extendr:masterfrom
CGMossa:copy-extendr-backports

Conversation

@CGMossa

@CGMossa CGMossa commented Jun 30, 2026

Copy link
Copy Markdown
Member

TODO: replace this line with your own framing, in your own voice.

AI-written details

Summary

  • R's C API is stabilizing: in R 4.5 several entry points (ENCLOS, Rf_findVar, Rf_findVarInFrame, CLOENV, BODY, FORMALS, DATAPTR, Rf_isFrame) became non-API and were replaced by compliant functions (R_ParentEnv, R_getVar, R_getVarEx, R_ClosureEnv, R_ClosureBody, R_ClosureFormals, DATAPTR_RO, Rf_isDataFrame). Code that targets both old and new R has to branch per version.
  • Ports extendr-ffi's backports module verbatim (with attribution) into src/backports.rs: small unsafe fn wrappers (get_parent_env, get_var, get_var_safe, get_var_in_frame, get_closure_env/body/formals, dataptr, is_data_frame) that dispatch to the correct entry point per R version.
  • The module declares its own cfg-gated extern block, so it does not depend on which symbols the committed bindings happen to include.
  • build.rs now emits r_4_4 / r_4_5 cfg flags (with matching rustc-check-cfg) for the module to gate on. These are internal to this crate.

Test plan

  • cargo build against R 4.6.0 (so r_4_5 is set): compiles, 0 errors.
  • Linkage check (run locally, not committed): calling backports::get_parent_env(R_GlobalEnv) and backports::is_data_frame(...) from the existing embedded-R test resolves and runs against R 4.6.0.
  • Build against an R < 4.5 (so the not(r_4_5) branch compiles and links the old entry points).

Notes

  • Copied rather than depended on, since libR-sys cannot depend on extendr-ffi.
  • Other extendr-ffi modules were considered and not copied: lib.rs/altrep.rs/graphics.rs/symbols.rs are a hand-curated subset of what libR-sys already generates; the idiomatic enums overlap with the existing Rboolean enum and the convert_to_rust_enums work; non_api.rs could follow later behind a feature if wanted.

Drafted by Claude (claude-opus-4-8). Reviewed by the author.

R's C API is stabilizing: several entry points used to access environments,
closures, variables and the data pointer became non-API in R 4.5, replaced by
new compliant functions. Code that needs to build against both old and new R
has to branch per version.

Port extendr-ffi's `backports` module (verbatim, with attribution): a set of
small `unsafe fn` wrappers (`get_parent_env`, `get_var`, `get_var_safe`,
`get_var_in_frame`, `get_closure_env/body/formals`, `dataptr`,
`is_data_frame`) that dispatch to the pre- or post-4.5 entry point. The module
declares its own cfg-gated `extern` block, so it does not depend on which
symbols the generated bindings happen to include.

build.rs now emits `r_4_4` / `r_4_5` cfg flags (with matching
`rustc-check-cfg`) for the module to gate on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant