Fix panic in printer when type-only export is body of an if statement#3928
Fix panic in printer when type-only export is body of an if statement#3928Copilot wants to merge 4 commits into
Conversation
When a type-only export (e.g., `export type {}`) is used as the body
of an if statement, the transformer elides it during emit, resulting
in a nil node being passed to emitEmbeddedStatement. Add a nil check
to emit a semicolon (empty statement) instead of panicking.
Fixes #1434
Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/e1fda50b-565f-4581-b127-a3a85ead111f
Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
| if node == nil { | ||
| p.writeLine() | ||
| p.increaseIndent() | ||
| p.writePunctuation(";") | ||
| p.decreaseIndent() | ||
| return | ||
| } |
There was a problem hiding this comment.
@copilot The original emitEmbeddedStatement in the old compiler did not need to nil check. Probably the bug is elsewhere
There was a problem hiding this comment.
You're right — the fix belongs upstream. Moved it to EmitContext.VisitEmbeddedStatement in 806c52e. When a visitor returns nil for a non-nil embedded statement (e.g., type-only export elided by the type eraser), it now creates an EmptyStatement instead of propagating nil. This matches the existing NotEmittedStatement → EmptyStatement conversion in the same function. The printer is reverted to its original state.
Instead of nil-guarding in the printer's emitEmbeddedStatement, fix the upstream issue in EmitContext.VisitEmbeddedStatement. When a visitor returns nil for an embedded statement (e.g., type-only export elided by the type eraser), create an EmptyStatement instead of propagating nil. This matches the existing handling of NotEmittedStatement nodes. Fixes #1434 Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/d30d9b60-0d66-4539-b25a-e9d521e0c8d4 Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
…ches Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/d30d9b60-0d66-4539-b25a-e9d521e0c8d4 Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a printer panic when an embedded statement is elided during emit, such as a type-only export used as the body of an if statement.
Changes:
- Treat non-nil embedded statements that visit to
nilas empty statements. - Add a compiler regression test and accepted baselines for the invalid-but-emitted type-only export case.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
internal/printer/emitcontext.go |
Converts elided embedded statements into empty statements before printing. |
testdata/tests/cases/compiler/typeOnlyExportAsIfBody.ts |
Adds the regression test case. |
testdata/baselines/reference/compiler/typeOnlyExportAsIfBody.js |
Adds emitted JS baseline. |
testdata/baselines/reference/compiler/typeOnlyExportAsIfBody.errors.txt |
Adds diagnostic baseline. |
testdata/baselines/reference/compiler/typeOnlyExportAsIfBody.symbols |
Adds symbol baseline. |
testdata/baselines/reference/compiler/typeOnlyExportAsIfBody.types |
Adds type baseline. |
if (true) export type {};panics because the type-only export is elided during emit, leaving a nilThenStatement. The printer'semitEmbeddedStatementdereferences it unconditionally.EmitContext.VisitEmbeddedStatementto create anEmptyStatementwhen the visitor returnsnilfor a non-nil embedded statement node, consistent with the existingNotEmittedStatementhandling in the same functiontypeOnlyExportAsIfBody.tsOutput after fix: