Skip to content

Use public R C APIs for R 4.6 compatibility#2

Merged
programLyrique merged 6 commits into
mainfrom
fix-r-4-6-public-c-api
Jul 14, 2026
Merged

Use public R C APIs for R 4.6 compatibility#2
programLyrique merged 6 commits into
mainfrom
fix-r-4-6-public-c-api

Conversation

@programLyrique

Copy link
Copy Markdown
Contributor

Replace legacy/non-API R internals that are no longer available under R 4.6 headers. Allocate language objects directly with Rf_allocLang(), avoid Rf_findVarInFrame(), and rebuild transformed closures with R_mkClosure() while preserving the original environment and attributes.

This fixes installation failures such as:

imputesrcref.so: undefined symbol: SET_BODY

The srcref coordinate output was compared against the previous implementation under R 4.5.2 and matched after normalizing srcfile timestamps.

Replace legacy/non-API R internals that are no longer available under R 4.6 headers. Allocate language objects directly with Rf_allocLang(), avoid Rf_findVarInFrame(), and rebuild transformed closures with R_mkClosure() while preserving the original environment and attributes.

This fixes installation failures such as:

  imputesrcref.so: undefined symbol: SET_BODY

The srcref coordinate output was compared against the previous implementation under R 4.5.2 and matched after normalizing srcfile timestamps.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the package’s C code to avoid relying on R internals that are no longer available with R 4.6 headers, replacing them with public R APIs to restore build/install compatibility.

Changes:

  • Rebuild transformed functions using R_mkClosure() (preserving the original closure environment) and reapply attributes via attributes().
  • Replace legacy allocList(...); SET_TYPEOF(..., LANGSXP) patterns with Rf_allocLang() for language object allocation.
  • Replace Rf_findVarInFrame() usage with R_tryEvalSilent() when probing base bindings for SPECIALSXP.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/transform.c Uses public APIs (Rf_allocLang, R_mkClosure, attributes()) to construct transformed closures without internal setters.
src/srcref_sites.c Allocates language objects with Rf_allocLang() for R 4.6 header compatibility.
src/source_impute.c Allocates the sys.source call with Rf_allocLang() instead of mutating a list into a LANGSXP.
src/blacklist.c Avoids Rf_findVarInFrame() by evaluating symbols in R_BaseEnv via R_tryEvalSilent().

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@MatejKocourek

Copy link
Copy Markdown
Collaborator

Are there performance implications for this? Time to impute is included in our results for comparison against covr.
For example for avoiding Rf_findVarInFrame and instead calling eval?

@programLyrique

Copy link
Copy Markdown
Contributor Author

I have not benchmarked yet but I expect there would be a performance impact as it now copies instead of mutating place for the closures. I don't think the eval is a big cost though, as it is doing it on a symbol, and eval has a specific path for this.

No need to merge this now, but anyway, some of the functions used in the package are not public anymore in R 4.6 so the package will break.

@programLyrique
programLyrique merged commit 4f43591 into main Jul 14, 2026
5 checks passed
@programLyrique
programLyrique deleted the fix-r-4-6-public-c-api branch July 14, 2026 11:50
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.

3 participants