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

Compiler crash with RangeError: Map maximum size exceeded #55630

Closed
Grohden opened this issue Sep 4, 2023 · 4 comments · Fixed by #55851
Closed

Compiler crash with RangeError: Map maximum size exceeded #55630

Grohden opened this issue Sep 4, 2023 · 4 comments · Fixed by #55851
Assignees
Labels
Bug A bug in TypeScript Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output Fix Available A PR has been opened for this issue

Comments

@Grohden
Copy link

Grohden commented Sep 4, 2023

🔎 Search Terms

RangeError: Map maximum size exceeded
RangeError: Value undefined out of range for undefined options property undefined (node 16)
react types
antd types
fontawesome types

🕗 Version & Regression Information

  • This is a crash
  • I've tested this with the latest nightly (5.3.0-dev.20230904), 5.2.2 and 5.1.6
  • I was unable to test this on prior versions because I've converted my code to ts and it started to occur

⏯ Playground Link

No response

💻 Code

Simple file:

import React from 'react';
import {Menu} from 'antd';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';

type IconProp = React.ComponentProps<typeof FontAwesomeIcon>['icon'];

type Props =
  & React.PropsWithChildren<{ icon: IconProp }>
  & React.ComponentProps<typeof Menu.Item>

export const Item = ({icon}: Props) => {
  return <FontAwesomeIcon icon={icon}/>;
};

package.json

{
  "name": "ts-compiler-crash",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "@fortawesome/fontawesome-svg-core": "^6.4.2",
    "@fortawesome/react-fontawesome": "^0.2.0",
    "@types/react": "^18.2.21",
    "typescript": "^5.2.2",
    "antd": "~4.2.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es2019", "es6", "dom"],
    "module": "es6",
    "moduleResolution": "node",
    "sourceMap": true,
    "target": "es6",
    "jsx": "react",
    "noEmit": true,
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noFallthroughCasesInSwitch": true
  }
}

🙁 Actual behavior

Compiler crashes with

yarn tsc
yarn run v1.22.19
$ /Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/.bin/tsc
/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:116479
      throw e;
      ^

RangeError: Map maximum size exceeded
    at Map.set (<anonymous>)
    at recursiveTypeRelatedTo (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60782:18)
    at isRelatedTo (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60199:122)
    at typeRelatedToSomeType (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60460:25)
    at unionOrIntersectionRelatedTo (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60380:16)
    at structuredTypeRelatedToWorker (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60959:23)
    at structuredTypeRelatedTo (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60801:21)
    at recursiveTypeRelatedTo (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60754:19)
    at isRelatedTo (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60199:122)
    at eachTypeRelatedToType (/Users/gabrielrohden/Desktop/Projects/Personal/ts-compiler-crash/node_modules/typescript/lib/tsc.js:60555:25)

Node.js v18.17.1
error Command failed with exit code 1.

🙂 Expected behavior

The compiler to at least not crash :/

Additional information about the issue

There's a related issue #50290

But its closed, so I'm opening a new one since that one wasn't really fixed but workarounded

@sandersn sandersn added the Needs Investigation This issue needs a team member to investigate its status. label Sep 6, 2023
@sandersn sandersn added this to the TypeScript 5.3.0 milestone Sep 6, 2023
@ahejlsberg
Copy link
Member

The issue here is the very large (>30K members) IconName union in react-fontawesome. This union ends up being intersected with ReactNode (itself a union), resulting in an explosion of types. In this particular case it looks like we can solve the problem by reasoning about the (denormalized) origin type of the large union. The particular operation that causes the explosion of work is checking assignability of IconProp & ReactNode to IconProp, and from the origin type we know that the very large union produced by the normalization of IconProp & ReactNode originated in a simple intersection. Since for any two types A & B is assignable to both A and B we can introduce a fast pass shortcut based on the origin type.

I will put up a PR later today.

@ahejlsberg ahejlsberg self-assigned this Sep 22, 2023
@Grohden
Copy link
Author

Grohden commented Sep 22, 2023

@ahejlsberg this was kinda my fault, I've later just avoided the exploding union (omitted icon from one of the types)

It was just hard to tell what was the problem with the compiler crash. I've opened the issue just to see if its possible for the compiler to not crash and tell me "hey this is insane, I cannot do this here"

Anyway, thank you all for looking into that 🙏!

@ahejlsberg
Copy link
Member

@Grohden Agreed, we definitely should implement logic to avoid overflowing the relation caches. As a rule, compiler crashes are never acceptable!

@ahejlsberg
Copy link
Member

Shorter repro:

type Digits = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
type T1 = `${Digits}${Digits}${Digits}${Digits}` | undefined;
type T2 = { a: string } | { b: number };

function f1(x: T1, y: T1 & T2) {
    x = y;  // Crash!
}

@ahejlsberg ahejlsberg added Bug A bug in TypeScript Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output and removed Needs Investigation This issue needs a team member to investigate its status. labels Sep 25, 2023
@typescript-bot typescript-bot added the Fix Available A PR has been opened for this issue label Sep 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants