Skip to content

Commit 472d23e

Browse files
authored
Make r_env_poke_parent() use parent.env<- and make it internal (#1847)
1 parent 5a0d32c commit 472d23e

File tree

8 files changed

+29
-13
lines changed

8 files changed

+29
-13
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
static
2+
r_obj* env_get_sym(r_obj* env,
3+
r_obj* sym,
4+
bool inherit,
5+
r_obj* last,
6+
r_obj* closure_env);

src/internal/decl/env-decl.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
static
2-
r_obj* env_get_sym(r_obj* env,
3-
r_obj* sym,
4-
bool inherit,
5-
r_obj* last,
6-
r_obj* closure_env);
1+
static r_obj* env_poke_parent_call;

src/internal/env-binding.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "env.h"
44
#include "quo.h"
55

6-
#include "decl/env-decl.h"
6+
#include "decl/env-binding-decl.h"
77

88

99
r_obj* ffi_env_get(r_obj* env,

src/internal/env.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include <rlang.h>
22

3+
#include "decl/env-decl.h"
4+
35
void r_env_unbind_anywhere(r_obj* env, r_obj* sym) {
46
while (env != r_envs.empty) {
57
if (r_env_has(env, sym)) {
@@ -58,7 +60,18 @@ void r_env_unbind_anywhere_c_string(r_obj* env, const char* name) {
5860
r_env_unbind_anywhere_c_strings(env, names, 1);
5961
}
6062

63+
void r_env_poke_parent(r_obj* env, r_obj* new_parent) {
64+
r_eval_with_xy(env_poke_parent_call, env, new_parent, r_envs.base);
65+
}
66+
6167
r_obj* ffi_env_coalesce(r_obj* env, r_obj* from) {
6268
r_env_coalesce(env, from);
6369
return r_null;
6470
}
71+
72+
void rlang_init_env(void) {
73+
env_poke_parent_call = r_parse("`parent.env<-`(x, y)");
74+
r_preserve(env_poke_parent_call);
75+
}
76+
77+
static r_obj* env_poke_parent_call = NULL;

src/internal/env.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ void r_env_unbind_names(r_obj* env, r_obj* names);
1313
void r_env_unbind_c_string(r_obj* env, const char* name);
1414
void r_env_unbind_c_strings(r_obj* env, const char** strings, r_ssize n);
1515

16+
// Not part of the rlang C API.
17+
// Maybe one day we will get a blessed C API for `SET_ENCLOS()`.
18+
void r_env_poke_parent(r_obj* env, r_obj* new_parent);
1619

1720
#endif

src/internal/exported.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <rlang.h>
2+
#include "env.h"
23
#include "internal.h"
34
#include "utils.h"
45
#include "vec.h"
@@ -453,6 +454,9 @@ r_obj* ffi_lof_arr_push_back(r_obj* lof, r_obj* i, r_obj* value) {
453454
// env.c
454455

455456
r_obj* ffi_env_poke_parent(r_obj* env, r_obj* new_parent) {
457+
// For the R level API, we do our own checks on top of
458+
// what `r_env_poke_parent()` (really `base::parent.env<-`)
459+
// does to throw better user facing error messages
456460
if (R_IsNamespaceEnv(env)) {
457461
r_abort("Can't change the parent of a namespace environment");
458462
}

src/internal/internal.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ void rlang_init_internal(r_obj* ns) {
5656
rlang_init_cnd(ns);
5757
rlang_init_cnd_handlers(ns);
5858
rlang_init_dots(ns);
59+
rlang_init_env();
5960
rlang_init_expr_interp();
6061
rlang_init_eval_tidy();
6162
rlang_init_fn();

src/rlang/env.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ r_obj* r_env_parent(r_obj* env) {
4141
#endif
4242
}
4343

44-
// TODO: C API compliance
45-
static inline
46-
void r_env_poke_parent(r_obj* env, r_obj* new_parent) {
47-
SET_ENCLOS(env, new_parent);
48-
}
49-
5044
static inline
5145
bool r_is_environment(r_obj* x) {
5246
return TYPEOF(x) == ENVSXP;

0 commit comments

Comments
 (0)