[education/rkward/releases/0.8.3] rkward/rbackend: Cope with removal of FORMALS in R 4.6

Thomas Friedrichsmeier null at kde.org
Fri Apr 17 16:32:41 BST 2026


Git commit ee0214fb20fc701ba54d151d8cdcdfe5ddd7caf9 by Thomas Friedrichsmeier.
Committed on 17/04/2026 at 13:35.
Pushed by tfry into branch 'releases/0.8.3'.

Cope with removal of FORMALS in R 4.6

M  +7    -0    rkward/rbackend/rkrapi.cpp
M  +6    -1    rkward/rbackend/rkrapi.h
M  +2    -2    rkward/rbackend/rkstructuregetter.cpp

https://invent.kde.org/education/rkward/-/commit/ee0214fb20fc701ba54d151d8cdcdfe5ddd7caf9

diff --git a/rkward/rbackend/rkrapi.cpp b/rkward/rbackend/rkrapi.cpp
index 46b8626b0..979b2b0ad 100644
--- a/rkward/rbackend/rkrapi.cpp
+++ b/rkward/rbackend/rkrapi.cpp
@@ -30,4 +30,11 @@ void RFn::init(void *libr_dll_handle, void *(*dlsym_fun)(void *, const char *))
 #else
 	RK_DEBUG(RBACKEND, DL_DEBUG, "R lib already linked");
 #endif
+
+	// work around various incompatiblities between R versions
+	// R < 4.5.0
+	if (!R_ClosureFormals) {
+		RK_DEBUG(RBACKEND, DL_DEBUG, "Falling back from R_ClosureFormals to FORMALS (%p)", R_ClosureFormals);
+		R_ClosureFormals = reinterpret_cast<decltype(R_ClosureFormals)>(dlsym_fun(libr_dll_handle, "FORMALS"));
+	}
 }
diff --git a/rkward/rbackend/rkrapi.h b/rkward/rbackend/rkrapi.h
index 552d693f7..f8b8831c8 100644
--- a/rkward/rbackend/rkrapi.h
+++ b/rkward/rbackend/rkrapi.h
@@ -174,7 +174,12 @@ class RFn : public QObject {
 	IMPORT_R_API(GEgetDevice);
 	IMPORT_R_API(GEplayDisplayList);
 	IMPORT_R_API(R_CHAR);
-	IMPORT_R_API(FORMALS);
+#if (R_VERSION >= R_Version(4, 5, 0))
+	IMPORT_R_API(R_ClosureFormals);
+#else
+	// will be handled, manually, in init
+	static SEXP (*R_ClosureFormals)(SEXP);
+#endif
 	IMPORT_R_API(INTEGER);
 	IMPORT_R_API(LOGICAL);
 	IMPORT_R_API(LENGTH);
diff --git a/rkward/rbackend/rkstructuregetter.cpp b/rkward/rbackend/rkstructuregetter.cpp
index d2d1840b2..2fcd18f77 100644
--- a/rkward/rbackend/rkstructuregetter.cpp
+++ b/rkward/rbackend/rkstructuregetter.cpp
@@ -434,9 +434,9 @@ void RKStructureGetter::getStructureWorker(SEXP val, const QString &name, int ad
 		if (RFn::Rf_isPrimitive(value)) {
 			// primitives don't have formals, internally
 			auto args = RKRSupport::callSimpleFun(args_fun, value, baseenv);
-			if (!RFn::Rf_isNull(args)) formals_s = RFn::FORMALS(args);
+			if (!RFn::Rf_isNull(args)) formals_s = RFn::R_ClosureFormals(args);
 		} else {
-			formals_s = RFn::FORMALS(value);
+			formals_s = RFn::R_ClosureFormals(value);
 		}
 		RFn::Rf_protect(formals_s);
 



More information about the rkward-tracker mailing list