Skip to content

Fixes #21383 enable Mode.ReadPositions when reading annotation trees#25911

Open
soronpo wants to merge 1 commit intoscala:mainfrom
soronpo:claude/fix-scala3-21383-UYYZV
Open

Fixes #21383 enable Mode.ReadPositions when reading annotation trees#25911
soronpo wants to merge 1 commit intoscala:mainfrom
soronpo:claude/fix-scala3-21383-UYYZV

Conversation

@soronpo
Copy link
Copy Markdown
Contributor

@soronpo soronpo commented Apr 22, 2026

Annotation trees stored in TASTY are read lazily. When a macro inspects a symbol's annotations via Symbol.annotations/asExprOf and splices the annotation tree into its expansion, the spliced tree is later re-typed by InlineTyper (which extends ReTyper/Typer). During this re-typing the compiler asserts that every untyped tree has a span (Typer.assertPositioned).

For incremental compilation the enclosing unpickling does not use Mode.ReadPositions, so spanAt and sourcePathAt return NoSpan/"" and the deserialized annotation tree has NoSpan all the way down. That in turn makes the re-typing of the macro expansion crash with:

assertion failed: position not set for new
of class dotty.tools.dotc.ast.Trees$Select

This happens for any annotation argument whose tree gets embedded into a macro's output — the original report uses @SqlName on a case class that is then processed by the TableInfo transparent inline from magnum, but the bug is fully general.

Force Mode.ReadPositions (and refresh the source from the pickled source map) when materializing the lazy annotation tree, mirroring what is already done for inline method bodies. With the mode enabled the pickled spans are restored and the re-typer is happy.

Adds a self-contained regression test (tests/pos-macros/i21383) and an sbt incremental-compilation test (sbt-test/source-dependencies/i21383).

Fixes #21383

How much have you relied on LLM-based tools in this contribution?

Extensively, but it's a small fix.

How was the solution tested?

New automated tests (including the issue's reproducer, if applicable)

Annotation trees stored in TASTY are read lazily. When a macro inspects a
symbol's annotations via `Symbol.annotations`/`asExprOf` and splices the
annotation tree into its expansion, the spliced tree is later re-typed
by InlineTyper (which extends ReTyper/Typer). During this re-typing the
compiler asserts that every untyped tree has a span
(Typer.assertPositioned).

For incremental compilation the enclosing unpickling does not use
Mode.ReadPositions, so `spanAt` and `sourcePathAt` return NoSpan/"" and
the deserialized annotation tree has NoSpan all the way down. That in
turn makes the re-typing of the macro expansion crash with:

  assertion failed: position not set for new <AnnotClass>
    of class dotty.tools.dotc.ast.Trees$Select

This happens for any annotation argument whose tree gets embedded into
a macro's output — the original report uses @SqlName on a case class
that is then processed by the `TableInfo` transparent inline from
`magnum`, but the bug is fully general.

Force Mode.ReadPositions (and refresh the source from the pickled
source map) when materializing the lazy annotation tree, mirroring
what is already done for inline method bodies. With the mode enabled
the pickled spans are restored and the re-typer is happy.

Adds a self-contained regression test (`tests/pos-macros/i21383`) and
an sbt incremental-compilation test (`sbt-test/source-dependencies/i21383`).
@soronpo soronpo marked this pull request as ready for review April 22, 2026 19:45
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.

assertion failed: position not set for new com.augustnagro.magnum.SqlName # -1 of class dotty.tools.dotc.ast.Trees$Select

2 participants