Skip to content

Mark vars in AST of ||, &&, if, and unless as generated#15328

Open
arnodirlam wants to merge 1 commit intoelixir-lang:mainfrom
arnodirlam:fix/mark-vars-in-logical-operators-ast-as-generated
Open

Mark vars in AST of ||, &&, if, and unless as generated#15328
arnodirlam wants to merge 1 commit intoelixir-lang:mainfrom
arnodirlam:fix/mark-vars-in-logical-operators-ast-as-generated

Conversation

@arnodirlam
Copy link
Copy Markdown
Contributor

@arnodirlam arnodirlam commented Apr 30, 2026

Commit 19c628a introduced a private AST helper Kernel.x_is_false_or_nil/0 to add generated: true to a generated variable x in generated guards for of ||, &&, if, and unless (diff).

However, the variable x, on which the guards refer to, is not marked as generated: true, and thus has a different AST signature.

For reference, see this diff (expand to see lines 1070-1135).

This PR fixes this by adding another private AST helper Kernel.x_var/0 to add generated: true to the generated variables x as well.

@josevalim
Copy link
Copy Markdown
Member

Thank you @arnodirlam. Can you please explain when/why this change would be necessary?

@arnodirlam
Copy link
Copy Markdown
Contributor Author

I originally stumbled upon this in my library dx, which transforms the fully expanded AST of a module into something new (same approach as nx).

In particular, it matches the fully-expanded AST of code that originally was a && (pattern). This breaks with Elixir 1.20.0-rc.0, so I looked into it and traced it back to 19c628a.

And, to me, it seems like a mismatch being introduced there, because some instances of the generated x variable got the generated: true flag (those in the guards), but some didn't, but it's the same variable.

I don't know all the repercussions of adding a generated: true in the AST, so I might be missing something. But to me, it seems like it's the same variable and adding generated: true to the remaining instances makes the metadata correct and consistent.

@josevalim
Copy link
Copy Markdown
Member

You should not expect the different metadata nodes to be equal, even for the same var. the only expectation is that they will have the same counter or name-context pair (or version, if matching on stored definitions). Matching on macro output will have subtleties like this, because the expansion of a macro is not guaranteed to be compatible.

my suggestion is to replace && in the host code, like Nx replaces Kernel operators by its own, so it can more reliably match on shape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants