diff --git a/core/ast/src/scope.rs b/core/ast/src/scope.rs index a9177afdf36..572dd91c1bd 100644 --- a/core/ast/src/scope.rs +++ b/core/ast/src/scope.rs @@ -142,6 +142,24 @@ impl Scope { } } + /// Creates a deep clone of the scope, copying the bindings vector + /// so that runtime mutations (e.g. from `eval`) do not leak back + /// into the shared compile-time scope. + #[must_use] + pub fn deep_clone(&self) -> Self { + Self { + inner: Rc::new(Inner { + unique_id: self.inner.unique_id, + outer: self.inner.outer.clone(), + index: self.inner.index.clone(), + bindings: RefCell::new(self.inner.bindings.borrow().clone()), + function: self.inner.function, + this_escaped: self.inner.this_escaped.clone(), + context: self.inner.context.clone(), + }), + } + } + /// Checks if the scope has only local bindings. #[must_use] pub fn all_bindings_local(&self) -> bool { diff --git a/core/engine/src/environments/runtime/declarative/function.rs b/core/engine/src/environments/runtime/declarative/function.rs index 9e198882740..b872d62a432 100644 --- a/core/engine/src/environments/runtime/declarative/function.rs +++ b/core/engine/src/environments/runtime/declarative/function.rs @@ -15,11 +15,12 @@ pub(crate) struct FunctionEnvironment { impl FunctionEnvironment { /// Creates a new `FunctionEnvironment`. + #[allow(clippy::needless_pass_by_value)] pub(crate) fn new(bindings_count: u32, slots: FunctionSlots, scope: Scope) -> Self { Self { bindings: GcRefCell::new(vec![None; bindings_count as usize]), slots: Box::new(slots), - scope, + scope: scope.deep_clone(), } } diff --git a/core/macros/src/module.rs b/core/macros/src/module.rs index e4bfcff5fe0..d6b01e9e2a1 100644 --- a/core/macros/src/module.rs +++ b/core/macros/src/module.rs @@ -170,9 +170,7 @@ fn module_impl_impl(_args: ModuleArguments, mut mod_: ItemMod) -> SpannedResult< for item in mod_.content.map_or_else(Vec::new, |c| c.1).as_mut_slice() { // Check for skip attributes. - #[allow(clippy::collapsible_match)] - // Allowed because take_path_attr would borrow attrs as mutable - match item { + let skip = match item { Item::Const(ItemConst { attrs, .. }) | Item::Enum(ItemEnum { attrs, .. }) | Item::ExternCrate(ItemExternCrate { attrs, .. }) @@ -187,16 +185,16 @@ fn module_impl_impl(_args: ModuleArguments, mut mod_: ItemMod) -> SpannedResult< | Item::TraitAlias(ItemTraitAlias { attrs, .. }) | Item::Type(ItemType { attrs, .. }) | Item::Union(ItemUnion { attrs, .. }) - | Item::Use(ItemUse { attrs, .. }) => { - if take_path_attr(attrs, "skip") { - original_module_decl = quote! { - #original_module_decl - #item - }; - continue; - } - } - _ => {} + | Item::Use(ItemUse { attrs, .. }) => take_path_attr(attrs, "skip"), + _ => false, + }; + + if skip { + original_module_decl = quote! { + #original_module_decl + #item + }; + continue; } let result = match item {