Linter for detecting disjoint type arguments on selected methods
commitaf69d7c9e211152977dd0003cdd81011a89c79a1
authorAndrew Kennedy <akenn@fb.com>
Sun, 18 Jul 2021 11:39:51 +0000 (18 04:39 -0700)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Sun, 18 Jul 2021 11:41:24 +0000 (18 04:41 -0700)
tree180d654e9a0910873416d46806cbbaac81172b59
parentc557c85ab13550a3fb421cb2f9dc0f60670a4e02
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
hphp/hack/src/naming/naming_special_names.ml
hphp/hsl/src/c/introspect.php