HHVM 4.0.0
HHVM 4.0 is released! This release adds support for .hack files, non-experimental support for HSL regular expressions, and removes several PHP behaviors.
PHP Is Unsupported
With this release, we no longer aim to be compatible with PHP. While this release does not ban <?php and similar tags, various changes make HHVM unable to execute most PHP projects. PHP-incompatible changes in this release mostly fit in to one of three goals:
- remove behavior that exists in PHP Arrays but not Hack Arrays or Hack Collections.
- deprecation of references
- removal of functions (or ways to invoke functions) that need to inspect or alter the caller frame such as
compact(),extract(),get_declared_variables(),func_get_args(), orparse_str()with a single argument.
We are considering removing support for <?php in the next release: the primary benefit would be a clearer error message (such as “HHVM no longer supports PHP code”) rather than more-specific messages such as parse errors which may be less useful. We welcome feedback on this via IRC, Facebook, or Twitter.
Using Composer
HHVM is no longer able to execute Composer; Composer 1.8.4 includes support for identifying the HHVM version when executing via PHP, which is how we currently recommend installing dependencies for Hack projects.
We are currently working to move to a package manager that fully supports multiple languages.
New Release Schedule
HHVM 4.1 will be released and supported following the current release schedule (i.e. released in 8 weeks, and then supported for 8 weeks). 4.2 will be released 1 week later, and mark the start of a weekly release schedule.
Each weekly release will receive security support for 6 weeks, and we are keeping the current long-term-release cycle: every 24 weeks, a release is made that will be supported for 48 weeks. This means that there will be up to 8 releases concurrently supported.
We recommend updating weekly, but holding back if a release is particularly painful. We decided on 6 weeks to also make monthly upgrades a workable option.
New Features
.hack File Extension
We now recommend using the .hack file extension if your editor/IDE support it; files with this extension are always strict, and do not require or allow a <? header line. For example, this is a complete .hack file:
1
2
3
4
5
6
7
#!/usr/bin/env hhvm
<<__EntryPoint>>
function main(): noreturn {
print("Hello, world!\n");
exit(0);
}
Other extensions such as .php and .hh remain supported, and require the <?hh header. We recommend only using these temporarily, for existing code - not for new projects.
It’s important to note that this means that HHVM will attempt to execute any .hack files that users can request, even if they do not include ‘<?’.
HH\lib\Regex is No Longer Experimental
The HH\Lib\Regex namespace is no longer part of hsl-experimental, and is now part of the main HSL project. The 3.28.2 release notes provide an overview of this feature.
Breaking changes
- return-by-reference is no longer supported
- Using references in combination with array_map, array_reduce, array_walk, array_walk_recursive, or array_filter has differing behavior in some edge cases, especially when the reference is mutated while iterating.
- ASP tags (
<% %>) are no longer supported - Functions that depend on the old C++ lexer and parser (instead of HackC) have been removed. This includes
token_get_all(),token_name(),php_strip_whitespace(),show_source(),highlight_file(), andhighlight_string(); these functions have been unable to fully handle Hack code since 3.27. create_function()has been removed; use lambdas or closures instead.- Our Docker images are now based on Ubuntu 18.04 instead of Ubuntu 16.04.
- Generators no longer auto-prime; they should ideally be accessed via
foreach. For manual iteration,->next()must be called before accessing the values. - All by-ref parameters must be marked with
&at the callsite. This was previously a typechecker error, and is now also a runtime error. - Variable-variables (
$$foo) are no longer supported parse_str()now requires two argumentsassert()will no longer evaluate string argumentsextract()has been removedcompact()has been removed
Future Changes
- With the exception of
.hackfiles, specifying a mode will be required; for example,<?hh // strictwill remain valid, but<?hhby itself will not. We recommend moving to.hackfiles if possible, otherwise<?hh // strict. If neither is immediately practical,<?hhcan be replaced with<?hh // partial. You can enable this behavior with the “default_mode=error”.hhconfigoption. - Non-top-level declarations will no longer be supported. For example, it will no longer be possible to declare classes or functions from other functions, or from
ifstatements. In 4.0, you can disable support via thehhvm.hack.lang.phpism.disable_nontoplevel_declarationsINI setting. - The operator precedence of
awaitwill be changing, to allowawaitto be used as an expression. You can enable the new precedence with thehhvm.hack.lang.enable_stronger_await_binding=trueINI setting - in problematic cases, this will lead to await being parsed as an expression, which will currently raise an error. We expect this to mostly affect await statements using the ternary operator, such asawait $foo ? $bar : $baz; currently, this is parsed asawait ($foo ? $bar : $baz), but in future releases it will be parsed as(await $foo) ? $bar : $baz.hhast-migrate --await-precedencecan be used to add parentheses automatically. - Support for the
hhvm.enable_zend_sortingoption will be removed. This option makes HHVM use a slower, PHP-compatible sorting algorithm, which has different behavior in edge cases such as when elements compare as equal. - Reference assignment (
$x =& $y) will be removed. Thedisallow_assign_by_reftypechecker option can be used to opt-in to this behavior now. - It will no longer be possible to take references to superglobals in 4.1, e.g.
some_function(&$_GET) - The
globalkeyword will be removed, e.g.function foo() { global $bar; } - Support for static locals will be removed by 4.2 (
function f() { static $foo = 42; return ++$foo; }); we plan to provide an optional ban in 4.1 func_num_args,func_get_args, andfunc_get_argwill be removed in 4.1. Use variadics instead.- Providing too few or too many arguments to a function will be an error
get_defined_vars()will be removedget_class()will require an argument.get_called_class()will be removed.get_class_vars()will be removed.- Passing the wrong types to builtins will throw, instead of returning false or null. You can enable logging for this with the
hhvm.warn_on_coerce_builtin_paramsINI setting. - Builtins will respect method visibility when invoking array callbacks - e.g.
array_map([$this, 'privateFunc'], $arr)will fail as array_map is not part of the class. - Type parameters will no longer be able to shadow global type names; for example,
class T<T> {}will be invalid. - Several behaviors will be removed from PHP arrays; the general principle is that PHP arrays should work as “vec or dict”. Notices can be enabled for these behaviors by setting both the
hhvm.hack_arr_compat_noticesoption and the associated notice options listed below:- Int-like string keys will not be converted to integers. Set
hhvm.hack_arr_compat_check_intish_castto raise notices. - Binding references to array elements will not be permitted. Set
hhvm.hack_arr_compat_check_ref_bindto raise notices. - The values
null,false, or uninitialized variables will not be able to be treated as arrays. Sethhvm.hack_arr_compat_check_falsey_promoteto raise notices. - Empty strings will not be able to be treated as arrays. Set
hhvm.hack_arr_compat_check_empty_string_promoteto raise notices. - Arrays will not be able to be compared to non-arrays. Setting
hhvm.hack_arr_compat_check_comparewill raise notices for ordering comparisons between arrays and non-arrays (scalars and objects) and for equality comparisons between arrays and Hack arrays. For example,[] > 3or[] === vec[] - Non-
arraykeyvalues will not be able to be used as array keys and will not be automatically coerced. Sethhvm.hack_arr_compat_check_array_key_castto raise notices. For example,falsewill no longer be converted to 0,nullwill not be converted to"", and1.23will no longer be automatically converted to1or"1.23"depending on the context. - Arrays will not be able to be used with the plus (
+) operator. Sethhvm.hack_arr_compat_check_array_plusto raise notices.
- Int-like string keys will not be converted to integers. Set
Additionally, several ‘future changes’ that were announced with 3.30 are still planned:
- ints will wrap in future releases, instead of being converted to floats, allowing the type of
int + intto beint, instead ofint + int = num. This behavior can be enabled with thehhvm.hack.lang.ints_overflow_to_intsINI setting - PHP-style anonymous functions will no longer support by-ref
use()parameters. This restriction can be enabled in the typechecker by adding thedisallow_anon_use_capture_by_ref.hhconfigoption gotowill no longer be supported in Hack files. This restriction can be enabled in the type-checker by adding thedisallow_goto.hhconfigoption- Runtime namespace fallback support for constants will be removed (
hhvm.hack.lang.phpism.undefined_const_fallback) - Undefined constants will no longer be converted to strings (‘barewords’ -
hhvm.hack.lang.phpism.undefined_const_as_string) - Variables called
$php_errormsgor$http_response_headerwill no longer be special (hhvm.hack.lang.phpism.disable_reserved_variables) - Casting objects to strings will no longer be supported (
hhvm.fatal_on_convert_object_to_string); this includes removal of support for__toString() - Array-access on non-builtins will no longer be supported (a notice will be raised if
hhvm.notice_on_array_access_useis enabled) - Several functions with special runtime behavior will be removed:
constant():hhvm.hack.lang.phpism.disable_constantdefine():hhvm.hack.lang.phpism.disable_defineforward_static_call():hhvm.hack.lang.phpism.disable_forward_static_callforward_static_call_array():hhvm.hack.lang.phpism.disable_forward_static_call_arraycall_user_func():hhvm.hack.lang.phpism.disable_call_user_funccall_user_func_array():hhvm.hack.lang.phpism.disable_call_user_func_array