-
-
Notifications
You must be signed in to change notification settings - Fork 335
Closed
Description
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
- Found during review of PR feat: ast-grep Parser Abstratction (Part 1, Node) #1940
- Discussed in: feat: ast-grep Parser Abstratction (Part 1, Node) #1940 (comment)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels