HHVM 4.66
HHVM 4.66 is released! This release marks the end of support for 4.59; HHVM 4.60–4.65 remain supported, as do the 4.32 and 4.56 LTS releases.
Highlights
HH\is_any_array()now refines the type of its argument toKeyedContainer. This doesn’t change what programs are accepted by the typechecker, but results in clearer error messages for those that aren’t.
Breaking Changes
- Casting any array (
vec,dict,keyset,varray,darray) tostringnow throws an exception at runtime. It had already been a typechecker error. - Using a non-int/string array index is now a runtime error. It had
already been a typechecker error.
- In recent HHVM versions, this behavior can be enabled using the INI options
hhvm.hack_arr_compat_notices=1andhhvm.hack_arr_compat_check_array_key_cast=1.
- In recent HHVM versions, this behavior can be enabled using the INI options
- Fixed a bug that caused
strtr(), when called with adarraythat contains int-like keys, to silently ignore them (strtr('123', darray['2' => 'x'])now correctly returns'1x3'). The behavior is now consistent withdict, which wasn’t affected by this bug. - The typechecker now reports an error if there are multiple
<<__EntryPoint>>functions in a file. It had already been a runtime error. - The typechecker now reports an error when comparing an enum value with a value of an incompatible primitive type. This may reveal new errors of the form “This expression is always false”.
- Fixed a bug where the typechecker would not report an error when a trait with
generic parameters that depend on each other is used incorrectly (e.g.
trait Foo<Ta, Tb as Ta>withuse Foo<string, int>). This may reveal previously undetected errors. - Fixed a bug that caused the typechecker to incorrectly conflate generic types on a class and its methods in some cases. This may reveal previously undetected errors (example).
Future Changes
- “plain arrays” (PHP arrays created by
array(...)) are going away. In a previous release, we eliminated the Hack syntax for these arrays, but some builtins (e.g.array_intersect_key()and many other array builtins) could still produce them. We will change these builtins to returndarrayinstead.- darrays behave nearly identically to plain arrays. The full list of
behavior differences is as follows:
- Plain arrays support relational comparison (
<,<=,>,>=); darrays throw on comparison. - Plain arrays don’t compare equal to darrays with the same elements.
- Plain arrays fail darray typehints, while darrays pass them.
- Plain arrays support relational comparison (
- The typehint behavior difference shouldn’t cause problems; it only affects behavior that currently causes TypehintViolationException which should be quite uncommon.
- For the comparison cases, turn on:
hhvm.hack_arr_compat_noticesandhhvm.hack_arr_compat_check_compareand look for the following two notices:- “Comparing two plain arrays relationally”
- “Comparing plain array and darray”
- The first notice here will become an error; the second one may return true where it currently returns false (and so requires manual inspection). We don’t expect either case to be common.
- darrays behave nearly identically to plain arrays. The full list of
behavior differences is as follows:
- If a function has a parameter with an invalid default value, accessing it via
ReflectionFunctionorReflectionMethodmay currently throw. In the future, it will only raise a warning (making reflection safer to use).- Use the INI option
hhvm.fix_default_arg_reflection=2to enable the future behavior now.
- Use the INI option
- In the future, using
class_methwith an abstract function will be a runtime error. Currently, this is only a runtime error if the method is actually called.- Use the INI options
hhvm.emit_cls_meth_pointers=1andhhvm.is_compatible_cls_meth_type=1to enable this behavior now.
- Use the INI options
- Output of
var_dump()will start differentiating betweenvarrays anddarrays.- Use the INI option
hhvm.hack_arr_dv_arr_var_dump=1to enable this behavior now.
- Use the INI option