Skip to content

Conversation

@alexreinking
Copy link
Member

This follows the implementation of std::visit, using a struct to accumulate function overloads and then dispatching to the correct one at compile time (using std::is_invocable_v). The result is the ability to define mutators that capture local state. I convert a few visitors in the codebase as a means to achieve some test coverage.

For example, this is the code for expand_expr inside StorageFlattening.cpp:

// Perform all the substitutions in a scope
static Expr expand_expr(const Expr &e, const Scope<Expr> &scope) {
    Expr result = LambdaMutator{
        [&](const Variable *var, auto *mut) -> Expr {
            if (const Expr *value = scope.find(var->name)) {
                // Mutate the expression, so lets can get replaced recursively.
                Expr expr = mut->mutate(*value);
                debug(4) << "Fully expanded " << var->name << " -> " << expr << "\n";
                return expr;
            }
            return var;
        }}.mutate(e);
    debug(4) << "Expanded " << e << " into " << result << "\n";
    return result;
}

We need the pointer to the mutator as the second argument.

@alexreinking alexreinking requested a review from abadams November 19, 2025 19:58
@alexreinking
Copy link
Member Author

If we like this direction, we can make a version for visitors, too.

@alexreinking
Copy link
Member Author

We can also consider adding mutate_with and mutate_with_generic helpers that immediately construct the LambdaMutator and call .mutate on it, which will simplify some call sites.

@alexreinking
Copy link
Member Author

We can also consider adding mutate_with and mutate_with_generic helpers that immediately construct the LambdaMutator and call .mutate on it, which will simplify some call sites.

I went ahead and did this -- clang-format decides to add a line, but I prefer how the functional form reads.

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.

2 participants