You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[flow] better handing of unions in type guard checks
Summary:
This change tries to prevent performance regression in code like the following
```
declare var x: T;
declare var foo: (x: mixed) => x is T
if (foo(x)) {}
```
where T is a large enum-like union.
Before this change, `predicate_no_concretization` on a `LatentP` predicate would do concretize all types, including unions, leading to the breakup of the type of the large union `T`. In `types_differ`, each member of `T` is compared against each member of the type guard type, which also happens to be `T`. This effectively yields a O(n^2) operation which becomes too slow on large enough `T`s.
This diff tries to address this by introducing a layer of faster checks before we get to the slow check above. Specifically,
1. we make the initial concretization preserve enum-like unions (which tend to be large)
2. we use fast comparison of this concretized type against the guard (`try_intersect`)
3. if we don't reach a good result, we proceed to concretize the input again, this time using full concretization on unions.
4. for each part of the newly concretized input, we run the same comparison against the guard (`try_intersect`)
Changelog: [internal]
Reviewed By: SamChou19815
Differential Revision: D69762017
fbshipit-source-id: 39f0af1541f3646c977cdc8860290a2c298fd622
0 commit comments