-
Notifications
You must be signed in to change notification settings - Fork 13k
Fix caching of union constituent instantiations that share a declaration #41003
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
Conversation
@typescript-bot perf test this |
Heya @andrewbranch, I've started to run the perf test suite on this PR at 1398152. You can monitor the build here. Update: The results are in! |
@andrewbranch Here they are:Comparison Report - master..41003
System
Hosts
Scenarios
|
Of course, a huge increase for material-ui, <0.5% difference everywhere else 🤦 |
@typescript-bot perf test this |
Heya @andrewbranch, I've started to run the perf test suite on this PR at 2d9829d. You can monitor the build here. Update: The results are in! |
Heya @andrewbranch, I've started to run the tarball bundle task on this PR at 2d9829d. You can monitor the build here. |
Hey @andrewbranch, 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. |
@andrewbranch Here they are:Comparison Report - master..41003
System
Hosts
Scenarios
|
This is now strictly better than the current behavior, and has identical caching/performance characteristics, but I’m unsure whether it’s a complete fix. (That is, there may be more cases where returning a cached instantiation is wrong.) |
@andrewbranch It's not immediately obvious to me what's going on here. Would you mind explaining what the core issue is? |
I’ll describe what happens before this change. This code errors because “No overload matches this call” on the interface Success {
isSuccess: true;
}
interface Fail {
isSuccess: false;
}
function bar<Q>(a: (Success | Fail)[]) {
a
.map(item => ({...item}))
.filter(value => {
return value.isSuccess;
});
} The error elaboration for the overload that ought to match is
and quick info on The first important thing that happens is the spread in the Where the problem arises is during signature resolution for interface Array<T> {
// ...
filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
// ...
} and try to infer We instantiate each union constituent through So in short, the union |
Hmm, that's pretty subtle. The issue is that the logic in |
#41084 is what I think is the correct fix. |
Ah, the first thing I tried was effectively equivalent to moving the cache to the |
Not ready for review.
Fixes #40995