Linter for detecting disjoint type arguments on selected methods
Summary:
Sometimes it is a bad code smell to invoke a method with arguments whose types are disjoint. In particular, methods whose logic ensures that the result is constant in such situations: for example, comparisons between values, or membership of collections.
Given a suitable signature for such methods, we can arrange that Hack infers generic parameters corresponding to the types that are expected to be non-disjoint. For example:
```
// Return true if values are identical
// (Will always return false if T1 and T2 are disjoint)
function are_the_same<T1,T2>(T1 $x, T2 $y):bool;
// Return index of first matching value, or null if not found
// (Will always return null if T1 and T2 are disjoint)
function find_element<T1,T2>(Traversable<T1> $t, T2 $element) : ?int;
```
This diff adds a new lint rule that is triggered when the attribute `<<__NonDisjoint>>` is present on at least two generic type parameters to a method. For example:
```
function are_the_same< <<__NonDisjoint>> T1, <<__NonDisjoint>> T2>(T1 $x, T2 $y):bool;
```
Calls to methods so marked have their inferred type arguments inspected, and using the new test for disjointness introduced by
D29067628 (https://github.com/facebook/hhvm/commit/
4dfb369fd5e8d3f51841f9129f2036467a73a7d4), we determine if the types are definitely disjoint. If not, a lint error of the form
```
This call to 'are_the_same' will always return the same value, because type string is disjoint from type int. (Lint[5627])
```
Differential Revision:
D19178676
fbshipit-source-id:
1ff81cc7d7d5f2fd5d5194815ccad02ac57a36ce