Deal with final types specially when constructing unions
Summary:
Constructing a union of n types involves potentially O(n^2) subtype operations as elements are union'ed pairwise. A common case that performs badly is
```
vec[C1::class, ... , Cn::class]
```
that produces a type
```
vec<classname<exact C1> | ... | classname<exact Cn>>
```
with n incomparable components, but requires O(n^2) operations in order to discover this!
An easy fix is the following: first split the types into "final" and "non-final" elements, where "final" means "there are no non-empty subtypes". This is the case for final and exact classes, and `classname<C>` where `C` is itself final. Use quadratic simplification on the non-final elements, but for the final elements, compare them against the non-final elements and eliminate any that are subtypes. Overall, this is O(n^2 + mn) where m is the number of final types and n is the number of non-final types.
Differential Revision:
D30132822
fbshipit-source-id:
6ab36818ec2a7d73c8f723401480918ad0c12e44