Skip to content

Out of memory crash with noErrorTruncation #37230

@mprobst

Description

@mprobst

TypeScript Version: Version 3.9.0-dev.20200305

Search Terms:

JavaScript heap out of memory, oom, noErrorTruncation

Code

import 'jasmine';
import 'figma';

declare function exp<T>(actual: ArrayLike<T>): jasmine.ArrayLikeMatchers<T>;
declare function exp<T>(actual: T): jasmine.Matchers<T>;

const selection: SceneNode[] = [];
const frames: FrameNode[] = [];
exp(frames).toEqual(selection);

Install the required types (npm install @types/jasmine @types/figma), then run tsc --noErrorTruncation

Expected behavior:

Report an error due to frames not having the same type as selection.

Actual behavior:

TypeScript crashes with OOM:

    0: ExitFrame [pc: 0x134e879]
Security context: 0x0db089340919 <JSObject>
    1: typeToTypeNodeHelper(aka typeToTypeNodeHelper) [0x30aa8fe76f81] [/usr/local/google/home/martinprobst/.config/yarn/global/node_modules/typescript/lib/tsc.js:~29667] [pc
=0x139e7d8b8e3b](this=0x1b27d36004d1 <undefined>,0x1a24cbd9b629 <Type map = 0x3d5b18402439>,0x299249254b31 <Object map = 0x3d5b1840d1a9>)
    2: typeReferenceToTypeNode(aka typeReferenceToTyp...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x9bcb80 node::Abort() [node]
 2: 0x9bdd16 node::OnFatalError(char const*, char const*) [node]
 3: 0xb1948e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb19809 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]

I strongly suspect TypeScript runs into an (at least effectively) infinite loop here: this crashes with 2 GB max heap for node, but also with 8 GB.

From a bit of debugging, it seems that TypeScript endlessly recurses through Jasmine's ExpectedRecursive<T> type:

declare namespace jasmine {
    // ...
    type ExpectedRecursive<T> = T | ObjectContaining<T> | AsymmetricMatcher<any> | {
        [K in keyof T]: ExpectedRecursive<T[K]> | Any;
    };
}

As it tries to produce a diagnostic string via typeToTypeNode, it keeps coming through the anonymous inline type here.

Playground Link: n/a (though probably possible to reduce the required type signatures from @types)

Related Issues: n/a

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptCrashFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad output

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions