Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RangeError: Maximum call stack size exceeded in TS 2.1.4 #12735

Closed
forabi opened this issue Dec 7, 2016 · 23 comments · Fixed by #12808
Closed

RangeError: Maximum call stack size exceeded in TS 2.1.4 #12735

forabi opened this issue Dec 7, 2016 · 23 comments · Fixed by #12808
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue

Comments

@forabi
Copy link

forabi commented Dec 7, 2016

TypeScript Version: 2.1.4

The project used to compile without any issues on TS 2.0, but it fails after upgrading to TS 2.1.4 without changing any code. I would be happy to give access to the repo if it would help.

Expected behavior:
The code compiles without issues

Actual behavior:
RangeError: Maximum call stack size exceeded


ERROR in ./src/store/reducers/workspace/analysis/index.ts
Module build failed: RangeError: Maximum call stack size exceeded
    at checkExpressionWorker (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37911:39)
    at checkExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37894:42)
    at checkExpressionCached (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37793:38)
    at checkSpreadExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:34449:39)
    at checkExpressionWorker (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37974:28)
    at checkExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37894:42)
    at checkExpressionForMutableLocation (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37825:24)
    at checkArrayLiteral (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:34484:32)
    at checkExpressionWorker (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37933:28)
    at checkExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37894:42)
    at getTypeOfExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37879:20)
    at getAssignedTypeOfBinaryExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:32532:17)
    at getAssignedType (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:32554:28)
    at getInitialOrAssignedType (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:32605:17)
    at getTypeAtFlowAssignment (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:32904:69)
    at getTypeAtFlowNode (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:32839:32)
    at getTypeAtFlowLoopLabel (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:33050:36)
    at getTypeAtFlowNode (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:32858:29)
    at getFlowTypeOfReference (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:32814:51)
    at checkIdentifier (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:33538:28)
    at checkExpressionWorker (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37914:28)
    at checkExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37894:42)
    at checkExpressionCached (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37793:38)
    at checkSpreadExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:34449:39)
    at checkExpressionWorker (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37974:28)
    at checkExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37894:42)
    at checkExpressionForMutableLocation (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37825:24)
    at checkArrayLiteral (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:34484:32)
    at checkExpressionWorker (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37933:28)
    at checkExpression (/home/f/Projects/WebCeph/node_modules/typescript/lib/typescript.js:37894:42)
 @ ./src/store/reducers/workspace/index.ts 13:0-113
 @ ./src/index.tsx
@mhegazy
Copy link
Contributor

mhegazy commented Dec 7, 2016

we would need to look at the code that triggered this exception to be able to diagnose the issue. can you share the sources?

@mhegazy mhegazy added Bug A bug in TypeScript Needs More Info The issue still hasn't been fully clarified labels Dec 7, 2016
@forabi
Copy link
Author

forabi commented Dec 7, 2016

@mhegazy @sandersn I invited you to my private repo. Try to build the scale-origin branch with:

yarn
npm run prod

It should work fine, now try upgrading to TS 2.1 and build again.

@mhegazy
Copy link
Contributor

mhegazy commented Dec 7, 2016

mm.. does nto seem to reproduce on my box..

c:\test\12735\WebCeph>webpack --bail --progress
Hash: 9f18cc72158839fd04f5
Version: webpack 2.1.0-beta.27
Time: 20127ms
                               Asset       Size  Chunks             Chunk Names
4502ba795be584933131c195c7a53052.png  279 bytes          [emitted]
800608933790f1502ddb5dc9ba746f62.png    1.24 kB          [emitted]
      bundle_9f18cc72158839fd04f5.js    2.25 MB       0  [emitted]  bundle
         lib_9f18cc72158839fd04f5.js  764 bytes       1  [emitted]  lib
      common_9f18cc72158839fd04f5.js    1.39 MB       2  [emitted]  common
                          index.html  578 bytes          [emitted]
                               sw.js     206 kB          [emitted]
[1084] ./src/analyses nonrecursive .ts$/ 275 bytes {0} [built]
[1087] multi bundle 28 bytes {0} [built]
[1088] multi lib 316 bytes {1} [built]
    + 1086 hidden modules
Child serviceworker-plugin:
        + 6 hidden modules

@forabi
Copy link
Author

forabi commented Dec 8, 2016

Did you upgrade to 2.1? I've had the same issue on 2 machines (both running Linux) since the nightlies with node 7.2, 6.9 and 4.7.

@maghis
Copy link

maghis commented Dec 8, 2016

I have the same problem here, I'm porting a project to TS and I was getting a bunch compiler errors with 2.0.10, after updating to 2.1.4 tsc crashes.

@maghis
Copy link

maghis commented Dec 8, 2016

@forabi any chance you are using "declaration": true (--declaration)?

@sandersn
Copy link
Member

sandersn commented Dec 8, 2016

I got it to repro. I'm on Linux too, although the stack trace doesn't seem particularly Linux-influenced.

@sandersn
Copy link
Member

sandersn commented Dec 8, 2016

Also fails for npm run dev, although webpack-dashboard obscures the stack trace.

@forabi
Copy link
Author

forabi commented Dec 8, 2016

@maghis No. Here is my tsconfig.json:

{
  "compilerOptions": {
    "target": "es2015",
    "lib": [
        "es5",
        "es2015",
        "webworker",
        "dom"
    ],
    "outDir": "build/",
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "jsx": "react",
    "sourceMap": true,
    "module": "commonjs",
    "isolatedModules": true,
    "forceConsistentCasingInFileNames": true,
    "preserveConstEnums": true,
    "traceResolution": false,
    "noImplicitReturns": true,
    "pretty": true,
    "noUnusedParameters": true,
    "strictNullChecks": true,
    "noUnusedLocals": true,
    "noImplicitThis": true,
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "*": [
        "*",
        "src/*"
      ]
    }
  },
  "compileOnSave": true,
  "exclude": [
      "node_modules",
      "src/**/*.test.ts",
      "build/**"
  ]
}

@sandersn
Copy link
Member

sandersn commented Dec 8, 2016

Looks like the culprit is of the form acc = [...acc]

let acc: T[] = [];
for (const x of o1.xs) {
  acc = [...acc, a, ...o2.xs, ...f(o2), ...flatten(map(o2.xs, g)]
}

I anonymised the code since it's a private repo. It's src/store/reducers/workspace/analysis/index.ts:356 on the scale-origin branch for future reference. Commenting out this line prevents the error, or switching to
acc = acc.concat([a, ...o2.xs, etc]).

I'll try to reduce the repro down to something the size of that snippet. I don't know why checkExpression gets into a recursive loop; the type annotation on the declaration is given so it something must have been introduced before the point where we check the annotation. Perhaps the expanding array type code?

@forabi
Copy link
Author

forabi commented Dec 8, 2016

@sandersn Thanks for taking the time to investigate the issue :) The code does not seem so elegant but it used to compile with 2.0. Can I do something to help? Is it a Linux-specific issue? Can someone reproduce on a Mac?

@sandersn
Copy link
Member

sandersn commented Dec 8, 2016

I have the failing snippet pretty small, but I haven't got it to repro outside your project yet. I doubt that it is Linux-specific, although I think it is specific to your set of compiler options.

Here's what I have so far:

type Fake = { components: any };
export const getNestedComponents = (fake: Fake): Fake[] => {
    let additional: Fake[] = [];
    for (const subcomponent of fake.components) {
        console.log(subcomponent);
        additional = [
                ...additional,
        ];
    }
    return additional;
}

Obviously, additional = [...additional, ...otherStuff] inside of a loop is extremely common, so this should work.

It passes when I take out the loop, so I'm pretty sure it's a bug in control-flow analysis that triggers with some combination of the compiler options.

I think I touched array spread control flow when adding object spread, so that's probably where the bug is. But it might be in the expanding array types code, which is new as well, and relies heavily on control-flow analysis.

@mhegazy mhegazy added this to the TypeScript 2.1.5 milestone Dec 8, 2016
@sandersn
Copy link
Member

sandersn commented Dec 8, 2016

I found a fix and an even smaller repro, but still no isolated test. If, in checkSpreadExpression, I change checkExpressionCached to checkExpression, the infinite recursion no longer happens.

Here's the smaller repro. I stuck it in src/index.tsx and deleted the source of the rest of the project and it still repros when running webpack. So I need to find out what webpack is doing differently from our test harness.

let additional = [];
for (const subcomponent of []) {
    additional = [...additional];
}

@sandersn
Copy link
Member

sandersn commented Dec 8, 2016

It turns out the above program crashes with tsc too. However, this program crashes with webpack but not with tsc:

// @noImplicitAny: true
let additional: number[] = [];
for (const subcomponent of []) {
    additional = [...additional];
}

I'm debugging right now to find out why.

@maghis
Copy link

maghis commented Dec 9, 2016

@sandersn it's not 2.1.4 specific, in my project I can reproduce it with 2.0.10 too, by switching "declaration": true.
I've tried commenting all the spreads in my source but the result is the same. (maybe a dependency?)

@sandersn
Copy link
Member

sandersn commented Dec 9, 2016

@maghis that is a different bug then -- the one that @forabi found is exposed by the new (2.1) evolving array types feature, and only occurs with a self-assignment inside a loop. Can you file a new issue with a minimal repro?

@maghis
Copy link

maghis commented Dec 9, 2016

@sandersn I'm trying to repro, it's probably a coincidence, I had never seen it before.

@sandersn
Copy link
Member

sandersn commented Dec 9, 2016

The reason that webpack crashes both with and without the type annotation is that, when called from webpack, the global symbol table is empty, so no array types can be created as the checker starts. This creates a bunch of errors, but those are also not reported with this webpack configuration.

And without being able to check array types, the compiler just treats everything like an evolving array type, even if it has an annotation. Then it hits this bug.

@sandersn
Copy link
Member

Fix is up at #12808

@forabi
Copy link
Author

forabi commented Dec 10, 2016

@sandersn @mhegazy Thanks! Do you still need access to the repo?

@sandersn
Copy link
Member

Nope, the magic ingredient was loop + spread expression + no implicit any + evolving array types, and I don't need the original now that I know that.

There is still a (separate) bug in the way webpack invokes the compiler , so you might still want to play with your webpack configuration to see if you can get it to show you compile errors.

@forabi
Copy link
Author

forabi commented Dec 10, 2016

@sandersn Yeah, ts-loader is configured with transpileOnly: true so no type checking is performed. This is faster for development and I haven't released a stable version yet. Once the project is ready for production type checking (and tests) should be enabled.

@sandersn
Copy link
Member

Well, transpileOnly: true may not be correct then. The compiler is definitely checking your source, it's just that built-in types like array are missing.

@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Dec 13, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants