Skip to content

EEx block tag immediately followed by another tag does not parse — do block left unterminated and <% end %> orphaned #3956

Description

@sh41

An EEx block-opening tag whose very next thing is another EEx tag, with no template data between them, does not parse. The do block is left unterminated and <% end %> falls outside the tree as an error element, so nothing bound in the block resolves.

<%= if @ok do %><% total = 1 %><%= total %><% end %>

total should resolve to its binding, as the equivalent if ok do total = 1; total end does in plain Elixir. Instead the second tag is swallowed into the first:

ElixirEexTagImpl('<%= if @ok do %><% total = 1 %>')   <- both tags in one
  ElixirDoBlockImpl('do %><% total = 1')
    ElixirStabBodyImpl('total = 1')
    PsiErrorElementImpl('')                            <- unterminated
ElixirEexTagImpl('<%= total %>')
...
PsiErrorElementImpl('end')                             <- orphaned

Any template data before the first nested tag and it parses cleanly and total resolves:

<%= if @ok do %><p>a</p><% total = 1 %><%= total %><% end %>

So it's the adjacency of the two tags. Newlines between them make no difference.

Reproduced on current main in .eex, .leex and .heex. Distinct from #1793, #1414, #1509 and #1661, which are the Don't know how to resolve variable in match tripwire — nothing is logged here, the tree is just wrong — and from the Don't know how to find variable use scope family (#1772, #1831, #1851, #2389), a different message and call site.


Filed as part of an AI-assisted review of the backlog. A human checked this one before it was filed, but it might still be wrong — if any of it is, please say so here.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions