Ban globals in default args if ctx lacks AccessGlobals [1/2]
Summary:
Fixes the unsoundness by not introducing the AccessGlobals out of thin air
when a `function`'s context would not otherwise give this capability, e.g.:
function f(int $x = AnotherClass::$staticInt)[]
should _not_ be allowed (at the very least when called from a pure context),
but the typechecker previously allowed it. Therefore, check if `AccessGlobals`
is present before type-checking the parameter list and the matching arguments,
and _only then_ reintroduce the capability the `AcceessGlobals`. E.g.,
function g(int $x = Another::$staticInt)[defaults]
is sound to allow because `AccessGlobals` is contained in `defaults`.
---
However, this is still too conservative, since the above startegy rejects:
function h(int $x = readonly Another::$staticInt)[read_globals]
The extra precision comes at the cost of doing additional subtyping check:
ReadGlobals <: FUN_CTX
and if so, introducing `ReadGlobals` instead of `AccessGlobals` when
type-checking argument binding for a function call. As an optimization,
we could check that the default argument is marked `readonly` and then
only do the latter subtyping check but not the former.
This optimized approach will be considered as a separate change.
Reviewed By: vassilmladenov
Differential Revision:
D30547750
fbshipit-source-id:
8b3952e8d8db612684bb3f11bc5cf479301ef0d4