-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Enforce a size limit in getSpreadType #40755
Conversation
When a union is spread into a union, the sizes are multiplied, potentially resulting in an enormous union (especially if there are repeated spreads). This check detects cases that used to run out of memory. Fixes microsoft#40754
@typescript-bot user test this |
src/compiler/checker.ts
Outdated
const resultSize = (left as UnionType).types.length * (right as UnionType).types.length; | ||
if (resultSize > 100000) { | ||
tracing.instant(tracing.Phase.Check, "getSpreadType_DepthLimit", { leftId: left.id, rightId: right.id }); | ||
error(currentNode, Diagnostics.Spread_expression_produces_a_union_type_that_is_too_complex_to_represent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this error is going to be frustrating to encounter with it also providing a suggestion for a workaround. What is the general-form workaround? Casting something somewhere to any
? Should we add a related span/quickfix for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's a fix I'm sufficiently confident in to make it a quick fix. I gave this a new error number so that it would be easier to document/google.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did wonder about looking inside the union to figure out whether there's a smaller span we could squiggle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the real code where this arose, the mitigation I suggested was adding a cast to each spread with a pre-existing type that listed all possible properties (optionally). I imagine any
would also work, possible at the expense of completions and such.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is definitely fine, and, even if we broaden #34853 to fix the reported issue without an error (which I think we should consider), we'll still fundamentally need this as a fallback.
If we broaden #34853, I'd probably drop the limit substantially. I based it on what would still compile quickly in my toy example. |
@typescript-bot test this |
The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. |
Since there are no occurrences of my new error code in the user test baseline diff, I'm assuming I can ignore the failure. |
@typescript-bot pack this |
Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 6650496. You can monitor the build here. |
Heya @DanielRosenwasser, I've started to run the perf test suite on this PR at 6650496. You can monitor the build here. Update: The results are in! |
@typescript-bot test this |
Heya @DanielRosenwasser, I've started to run the extended test suite on this PR at 6650496. You can monitor the build here. |
src/compiler/checker.ts
Outdated
if (resultSize > 100000) { | ||
tracing.instant(tracing.Phase.Check, "getSpreadType_DepthLimit", { leftId: left.id, rightId: right.id }); | ||
error(currentNode, Diagnostics.Spread_expression_produces_a_union_type_that_is_too_complex_to_represent); | ||
return errorType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@minestarks raised an interesting point: should this be anyType
so that users have the option of ts-ignoring this error?
Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build. |
@DanielRosenwasser Here they are:Comparison Report - master..40755
System
Hosts
Scenarios
|
This should probably use |
When a union is spread into a union, the sizes are multiplied,
potentially resulting in an enormous union (especially if there are
repeated spreads). This check detects cases that used to run out of
memory.
Fixes #40754