Skip to content

Commit 086c642

Browse files
committed
Fix proc macros' hygiene issues, for compatibility with Rust 1.47
Without this fix, #[defun] calls generated by macro_rules sometimes fail with this error: ``` error[E0423]: expected value, found macro `env` ``` For example: https://github.com/ubolonton/emacs-tree-sitter/blob/0.11.0/src/lang.rs#L182 References: - https://github.com/rust-lang/rust/blob/1.47.0/RELEASES.md#compatibility-notes - rust-lang/rust#73084
1 parent d83a7ff commit 086c642

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

emacs-macros/src/func.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,29 +144,30 @@ impl LispFunc {
144144
let mut args = TokenStream2::new();
145145
// Inlined references do not live long enough. We need bindings for them.
146146
let mut bindings = TokenStream2::new();
147+
let env = Ident::new("env", Span::call_site());
147148
for arg in &self.args {
148149
match *arg {
149150
Arg::Env { span } => {
150151
// TODO: Find a way not to define inner function, somehow, otherwise the reported
151152
// error is confusing (i.e expecting Env, found &Env).
152-
args.append_all(quote_spanned!(span=> &**env,))
153+
args.append_all(quote_spanned!(span=> &**#env,))
153154
}
154155
Arg::Val { span, access, nth, .. } => {
155156
let name = util::arg("arg", nth);
156157
// TODO: Create a slice of `emacs_value` once and iterate through it, instead of
157158
// using `get_arg`, which creates a slice each call.
158159
bindings.append_all(match access {
159160
Access::Owned => quote_spanned! {span=>
160-
let #name = env.get_arg(#nth).into_rust()?;
161+
let #name = #env.get_arg(#nth).into_rust()?;
161162
},
162163
// TODO: Support RwLock/Mutex (for the use case of sharing data with
163164
// background Rust threads).
164165
// TODO: Support direct access.
165166
Access::Ref => quote_spanned! {span=>
166-
let #name = &*env.get_arg(#nth).into_ref()?;
167+
let #name = &*#env.get_arg(#nth).into_ref()?;
167168
},
168169
Access::RefMut => quote_spanned! {span=>
169-
let #name = &mut *env.get_arg(#nth).into_ref_mut()?;
170+
let #name = &mut *#env.get_arg(#nth).into_ref_mut()?;
170171
},
171172
});
172173
args.append_all(quote_spanned!(span=> #name,));
@@ -193,12 +194,12 @@ impl LispFunc {
193194
// XXX: output can be (), but we can't easily know when.
194195
let into_lisp = quote_spanned! {self.output_span=>
195196
#[allow(clippy::unit_arg)]
196-
::emacs::IntoLisp::into_lisp(output, env)
197+
::emacs::IntoLisp::into_lisp(output, #env)
197198
};
198199
let inner = &self.def.sig.ident;
199200
let wrapper = self.wrapper_ident();
200201
quote! {
201-
fn #wrapper(env: &::emacs::CallEnv) -> ::emacs::Result<::emacs::Value<'_>> {
202+
fn #wrapper(#env: &::emacs::CallEnv) -> ::emacs::Result<::emacs::Value<'_>> {
202203
#bindings
203204
let output = #inner(#args)?;
204205
#maybe_embed

emacs-macros/src/module.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,14 @@ impl Module {
111111

112112
pub fn gen_init(&self) -> TokenStream2 {
113113
let init = Self::init_ident();
114+
let env = quote!(env);
114115
let pre_init_fns = util::pre_init_path();
115116
let pre_init = quote! {
116117
{
117118
let funcs = #pre_init_fns.try_lock()
118119
.expect("Failed to acquire a read lock on the list of initializers");
119120
for func in funcs.iter() {
120-
func(env)?
121+
func(#env)?
121122
}
122123
}
123124
};
@@ -153,21 +154,21 @@ impl Module {
153154
{
154155
let funcs = #init_fns.try_lock()
155156
.expect("Failed to acquire a read lock on map of initializers");
156-
for (name, func) in funcs.iter() {
157-
func(env)?
157+
for (_, func) in funcs.iter() {
158+
func(#env)?
158159
}
159160
}
160161
};
161162
quote! {
162163
#[allow(non_snake_case)]
163-
fn #init(env: &::emacs::Env) -> ::emacs::Result<::emacs::Value<'_>> {
164+
fn #init(#env: &::emacs::Env) -> ::emacs::Result<::emacs::Value<'_>> {
164165
#pre_init
165166
let feature = #feature;
166167
#set_prefix
167168
#configure_mod_in_name
168169
#export_lisp_funcs
169-
#hook(env)?;
170-
env.provide(&feature)
170+
#hook(#env)?;
171+
#env.provide(&feature)
171172
}
172173
}
173174
}

0 commit comments

Comments
 (0)