Introduce the ConstFun attribute
Summary:
Before this diff, I was using `<<__Const>>` as the attribute for lambdas with constness, but afterwards I decided that `<<__ConstFun>>` was a better choice, since `<<__Const>>` can also be used on parameters to a constructor to mean that the property should be const, and I didn't want to confuse the concepts.It also allows us to enforce that `<<__ConstFun>>` only appear under the unstable feature.
<<__ConstFun>> is an attribute which, when placed on a function, method, or closure, enforces the following:
1. All parameters are automatically treated as readonly (without having to specify)
2. The $this type on a method is considered readonly, and the method is readonly
3. All values captured by a closure are readonly.
Implementation detail:
Note that <<__ConstFun>> is implemented as an attribute on parameters and on lambdas, but NOT on closure type specifiers. This is because we don't have an appropriate way to allow attributes on closure type specifiers in Hack, and adding new parsing syntax seems worse when we don't know what that syntax will look like. Instead, we adopt the following semantics:
<<__ConstFun>> on a lambda changes the function types' flag of is_const to true.
<<__ConstFun>> on a parameter is *only* valid when the parameter has a function typehint. We will enforce this with a NastCheck in the diff above.
If a function typehint is also annotated with `<<__ConstFun>>`, we only accept functions with `<<__ConstFun>>` on them(i.e.,`Typing_defs_flags.get_ft_is_const = true`) as input.
I know that this is kind of confusing from the implementation perspective, and once we decide on a valid syntax we should be able to get rid of it. For the prototype though, I think this will be fine.
Note that this means we do not allow properties that are function types to be marked `<<__ConstFun>>` (or function types in any other location besides on a parameter, for that matter). This is not unsound, since any ConstFun function is a subtype of a regular function of the same type, but it is incomplete. I do not know of any use cases where having a property function type be ConstFun would be useful, so I doubt this will matter. In the future, it may be helpful to allow a `<<__ConstFunReturn>>` attribute as well to return a const function, but something like that would need to be enforced like readonly as well, so it's not exactly easy to do.
Reviewed By: zilberstein
Differential Revision:
D26562108
fbshipit-source-id:
80e0b060c92213cc5bbca0bde5ea2f2d0b423bd0