Skip to content

Bug: And matcher leaks environment changes when the second matcher fails #1956

@coderabbitai

Description

@coderabbitai

Issue

The And matcher in ops.rs leaks environment changes when the second matcher fails.

Details

In And::match_node_with_env, the method mutates the shared environment through pattern1. If pattern2 subsequently fails, the mutation is never rolled back, resulting in a polluted metavariable environment even though the whole And pattern did not match.

Other combinators like Or, Any, and All already protect against this by using a local Cow and only committing on success. The And matcher should follow the same contract.

Proposed Fix

-  let node = self.pattern1.match_node_with_env(node, env)?;
-  self.pattern2.match_node_with_env(node, env)
+  // keep the original env intact until both arms match
+  let mut new_env = Cow::Borrowed(env.as_ref());
+  let node = self.pattern1.match_node_with_env(node, &mut new_env)?;
+  let ret  = self.pattern2.match_node_with_env(node, &mut new_env)?;
+  // both succeed – commit the combined env
+  *env = Cow::Owned(new_env.into_owned());
+  Some(ret)

Related Links

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions