microsoft / microsoft/TypeScript
Panic "Diagnostic emitted without context" ts-go in declaration emit for `export default` arrow/function expression with non-portable inferred return type
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.3k
- Merge medio
- 2g 4h
- PR unite (30g)
- 132
Descrizione
🔎 Search Terms
panic Diagnostic emitted without context, declaration emit crash, throwDiagnostic, handleSymbolAccessibilityError, transformExportAssignment, canProduceDiagnostics, export default arrow function, function expression, inferred return type cannot be named, symbol accessibility, TS4082, tsgo, native compiler
🕗 Version & Regression Information
- This changed between versions 6.0.3 and 7.0.0 the JS compiler emits TS4082 for this code; the native compiler panics
- This changed in commit or PR: same code path as microsoft/typescript-go#4629 ("Unknown parent for parameter: KindArrowFunction"), whose fix PR microsoft/typescript-go#4648 (merged 2026-07-15) covered the parameter-diagnostics panic but not this return-type-serialization panic which still reproduces on
typescript@next7.1.0-dev.20260819.1 - This is the behavior in every version I tried (
typescript@7.0.2,@typescript/native-preview7.0.0-dev.20260707.2,typescript@next7.1.0-dev.20260819.1), and I reviewed the FAQ for entries about declaration emit and "has or is using private name" errors — none cover compiler panics - I was unable to test this on versions before 7.0 because the panicking code path (native declaration emit's promotion of default-exported function expressions) does not exist in the JS compiler
⏯ Playground Link
No response
💻 Code
// @filename: helper.ts
declare const brand: unique symbol;
class Foo {
private [brand]: number = 1;
}
export function makeFoo() {
return new Foo();
}
// @filename: repro.ts
import { makeFoo } from './helper';
export default () => makeFoo();
// tsconfig.json
{ "compilerOptions": { "declaration": true, "emitDeclarationOnly": true, "outDir": "dist", "strict": true } }
Run tsc -p ..
Both ingredients are required: the default export must be an ExportAssignment whose expression is an
arrow function or function expression (export default function () {} at statement level is a
function declaration a different AST node and errors correctly), and the inferred return type
must contain a symbol that cannot be named from the exporting module.
🙁 Actual behavior
The whole compile crashes with a Go panic (exit code 2) instead of reporting a diagnostic:
panic: Diagnostic emitted without context [recovered, repanicked]
github.com/microsoft/typescript-go/internal/transformers/declarations.throwDiagnostic(...)
internal/transformers/declarations/transform.go:276
...(*SymbolTrackerImpl).handleSymbolAccessibilityError(...) // Accessibility = CannotBeNamed, ErrorNode = nil
internal/transformers/declarations/tracker.go:211
...(*NodeBuilderImpl).serializeReturnTypeForSignature
...(*DeclarationTransformer).ensureType transform.go:1647
...(*DeclarationTransformer).transformFunctionLikeToDeclaration
...(*DeclarationTransformer).transformExportAssignment transform.go:1223
In a large monorepo this also fires under noEmit + incremental (declaration transforms run for
buildinfo state), where transient stale-cache states can create the cannot be named condition on
otherwise-clean code making the crash appear nondeterministic.
🙂 Expected behavior
A normal diagnostic, as TypeScript 6.0.3 emits for the identical input:
repro.ts(3,1): error TS4082: Default export of the module has or is using private name 'brand'.
tsgo itself handles every neighbouring form correctly — only the expression-form default export panics:
| form | result (tsgo 7.0.2 / nightly) |
|---|---|
export default () => makeFoo(); |
panic |
export default (function () { … }); |
panic |
export default function () { … } (declaration) |
TS4058 ✓ |
export const make = () => makeFoo(); |
TS4023 + TS4094 ✓ |
Additional information about the issue
Root cause (verified at tag typescript/v7.0.2, commit 2bd066d8, and unchanged on current main):
visitSourceFileinstallsthrowDiagnosticliterallypanic("Diagnostic emitted without context")as the file-level defaultgetSymbolAccessibilityDiagnostic
(internal/transformers/declarations/transform.go:276, :289).transformExportAssignment'sast.IsFunctionLike(unwrapped)branch (transform.go ~1241 on main),
which promotesexport default <arrow/function expression>via
transformFunctionLikeToDeclaration → ensureType(unwrapped), returns without installing a
diagnostic context and withoutPushErrorFallbackNodeunlike the non-function fallback
branch just below it, which installsDefault_export_of_the_module_has_or_is_using_private_name_0
before serializing.ensureTypeinstalls a per-node handler onlyif canProduceDiagnostics(node)(transform.go ~1671
on main), andcanProduceDiagnostics(internal/transformers/declarations/util.go:25) does not
includeast.IsArrowFunction/ast.IsFunctionExpression.
So a SymbolAccessibilityCannotBeNamed result raised while serializing the arrow's inferred return
type reaches the panic stub and takes down the compiler.
Suggested minimal fix: in the IsFunctionLike branch, install the same default-export diagnostic
context (and PushErrorFallbackNode(assignment) / Pop) that the sibling fallback branch already
uses, before calling transformFunctionLikeToDeclaration. This restores parity with TS 6.x (TS4082).
Prior occurrences of the same panic via other triggers: microsoft/typescript-go#2522 (CommonJS .cjs
re-export — fixed for that trigger only), microsoft/typescript-go#3378 (LSP, closed unverified).
Observed in the wild: supabase/supabase#48876 (worked around by deleting the triggering code).
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Valutazione
Questa issue non è ancora stata valutata.