@@ -66,7 +66,8 @@ static_inline const char* digest(SEXP self, SEXP x) {
6666 // we need to mask the object in order to make `base::serialize` work
6767 SEXP xsym = install ("x" );
6868 SEXP new_env = PROTECT (Rf_lang3 (Rf_install ("::" ), Rf_install ("base" ), Rf_install ("new.env" )));
69- SEXP mask = PROTECT (Rf_eval (Rf_lang1 (new_env ), self ));
69+ SEXP new_env_call = PROTECT (Rf_lang1 (new_env ));
70+ SEXP mask = PROTECT (Rf_eval (new_env_call , self ));
7071 Rf_defineVar (xsym , x , mask );
7172 SEXP digestfun = PROTECT (get_sexp_value (self , "digest" ));
7273 SEXP l = PROTECT (Rf_lang2 (digestfun , xsym ));
@@ -76,7 +77,7 @@ static_inline const char* digest(SEXP self, SEXP x) {
7677 if (errorOccurred || TYPEOF (result ) != STRSXP ) {
7778 Rf_error ("cannot compute digest of the key" );
7879 }
79- UNPROTECT (4 );
80+ UNPROTECT (5 );
8081 return R_CHAR (Rf_asChar (result ));
8182}
8283
@@ -89,7 +90,11 @@ tommy_hash_t strhash(SEXP self, SEXP key) {
8990 } else if (Rf_isVector (key )) {
9091 key_c = digest (self , key );
9192 } else if (Rf_isFunction (key )) {
92- key_c = digest (self , BODY (key ));
93+ SEXP key2 = PROTECT (Rf_duplicate (key ));
94+ // the digest function will also hash the enclosure
95+ SET_CLOENV (key2 , R_NilValue );
96+ key_c = digest (self , key2 );
97+ UNPROTECT (1 );
9398 } else {
9499 const char * buf = R_alloc (sizeof (char ), 30 );
95100 sprintf ((char * ) buf , "<%p>" , key );
0 commit comments