Skip to content

[REFACTOR][RUST] Keep mutate dispatch state on the dispatcher - #728

Merged
tqchen merged 2 commits into
mainfrom
rust-mutator-owned-state
Sep 2, 2026
Merged

[REFACTOR][RUST] Keep mutate dispatch state on the dispatcher#728
tqchen merged 2 commits into
mainfrom
rust-mutator-owned-state

Conversation

@tlopex

@tlopex tlopex commented Sep 2, 2026

Copy link
Copy Markdown
Member

This PR makes typed structural mutation dispatch own its pass state directly.

Previously, #[dispatch(mutate)] separated the dispatch object from a State stored inside MutateCallbacks, requiring handlers to access state through mutator.state() or mutator.state_mut().

Now the state lives naturally on the dispatch object:

struct MyMutator {
    analyzer: Analyzer,
    // Other pass state.
}

#[tvm_ffi::dispatch(mutate)]
impl MyMutator {
    fn mutate_node(
        &mut self,
        value: Node,
        mutator: &mut Mutator,
    ) -> Result<Node> {
        let child = mutator.mutate(self, &value.child)?;
        // Rewrite or reuse the node.
    }
}

The responsibilities are now separated as follows:

  • The dispatch object owns pass-specific state.
  • #[dispatch(mutate)] selects the matching typed handler.
  • Mutator provides recursion, default mutation, variable remapping, and the current definition region.
  • Explicitly passing self during recursion creates a normal Rust mutable reborrow and avoids hidden aliasing through raw pointers.
  • Stateful closure callback chains continue to be supported through CallbackMutator<State> and MutateCallbacks.

The Rust guide and structural-mutation tests have been updated to use the new API. All relevant Rust tests, including the 47 structural-mutation tests, pass.

@tqchen
tqchen merged commit b33463a into main Sep 2, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants