Repository navigation
Keep the location of templates without interpolations through the v0 AST - #9165
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## template-segment-locs #9165 +/- ##
======================================================
Coverage 81.74% 81.75%
======================================================
Files 460 460
Lines 64953 64957 +4
======================================================
+ Hits 53099 53105 +6
+ Misses 11854 11852 -2
🚀 New features to boost your workflow:
|
rescript
@rescript/belt
@rescript/darwin-arm64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/runtime
@rescript/win32-x64
commit: |
|
Developer playground preview: https://rescript-lang.github.io/rescript/dev-playground/?version=pr-9165 |
Changelog🐛 Bug fix
Semantic Diff1 commit · Full page Keep the location of templates without interpolations through ast0506cb25 · cknitt + Claude · Nov 01, 2026, 08:57 UTC
AST modified (template after the v0 round trip) let z = `template`
parsed: expression [1,0+8]..[1,0+18]
-after the round trip: expression [1,0+8]..[1,0+17]
+after the round trip: expression [1,0+8]..[1,0+18] |
0347768 to
7ef4188
Compare
Why:
On the v0 wire, a template without interpolations was one string
constant at its segment's location, which ends before the closing
backquote, so the template lost one character of its location after a
PPX round trip. The constant now takes the template's location, and the
segment's location is derived from it on the way back (#9164).
AST modified (template after the v0 round trip):
Example:
let z = `template`
Before (text):
parsed: expression [1,0+8]..[1,0+18]
after the round trip: expression [1,0+8]..[1,0+17]
After (text):
parsed: expression [1,0+8]..[1,0+18]
after the round trip: expression [1,0+8]..[1,0+18]
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gJFAva9685fjvkajub
Signed-off-by: Christoph Knittel <ck@cca.io>
7ef4188 to
506cb25
Compare
|
Folded into #9166, which now contains this commit (506cb25). The two changes depend on each other: #9166 alone would have made the v0 round trip lose both backquotes of a template (see the Codex review there). GitHub marks this PR as merged because its base branch was fast-forwarded to include it; it lands on master with #9166. |
Fixes #9164. Stacked on #9166.
Why
PPXs receive the parsetree in the frozen v0 format:
Ast_mapper_to0converts it before they run, andAst_mapper_from0converts their output back. A template literal without interpolations came back from that round trip with a location one character short, missing its closing backquote:In projects with PPXs, everything that used the template's location, such as error highlights and editor ranges, ended one character early.
Cause
In the current parsetree, a template has two locations: the expression's, which covers the whole literal, and its segment's, which covers just the text (since #9166). The v0 AST has no template node. A template without interpolations is a single string constant marked
res.template, and a constant has one location only.Ast_mapper_to0built that constant at the segment's location.Ast_mapper_from0then used it for both the expression and the segment, so the expression lost its backquotes.Templates with interpolations were never affected. In v0 they are a chain of
^applications, whose outer node carries the expression's location, and each segment constant keeps its own:What changes
Ast_mapper_to0: the single constant of a template without interpolations takes the template's location, backquotes included.Ast_mapper_from0: the segment's location is derived from it as the text between the backquotes, one character in from each end. Ghost locations, and ones too short to hold two backquotes, are kept as they are, so templates that PPXs build withLocation.nonestay as they were.Interpolated templates, tagged templates and
%rawtemplates have their own v0 encodings and don't change.Tests
template_locations_roundtrip_through_ast0inounit_ast_mapper0_tests.mlround-trips a whole file through v0 and checks the tree is identical, locations included:Without the fix it fails on the first binding.
Once this and #9161 are in,
todo_roundtrips_through_ast0can include a template message.🤖 Generated with Claude Code
https://claude.ai/code/session_01Kbf3gJFAva9685fjvkajub