Generate fresh type parameters away from others in same method body
Summary:
When refining to a generic type, we generate "fresh" abstract types with names derived from the generic parameters. For example, `$x is C<_>` for a generic class `class C<Tc> { ... }` would generate a name such as `Tc#1`.
We generate names "away from" existing generic parameters. Unfortunately, they may clash with other names generated in the same body, and end up flowing to a common place. This is unsound. For example:
```
if ($b) {
invariant($y is C<_>, "C");
} else {
invariant($y is D<_>, "D");
}
```
This might generate the *same* name for the abstract type parameter in both branches of the conditional, which then leaks out at the join point. See the test in this diff for an example of a program that should be rejected but which is currently accepted.
The fix is easy: maintain in `env` a set of already-generated type parameter names. Fresh names should be generated "away" from these.
Reviewed By: kmeht
Differential Revision:
D16200769
fbshipit-source-id:
9a251039d296596b732be01d8ed9052feaf9c5a5