-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HHVM and PHP7 differ on type annotations on internal functions (rtrim in particular) #7198
Comments
The typechecker understands only a few PHP7 features, and for all of the BC breaks, takes the PHP5 behaviour. Basically it follows the same logic as HHVM with |
Hmm, well is there a more elegant way to have HHVM emulate the PHP7 default behavior example above? Currently the example is preventing code that should work in PHP7 from running under HHVM in php7.all mode, and I worry about the side effects from the below "work-around" configuration:
Otherwise at the very least I think it makes sense to better document the expected divergence in PHP7 behavior. Or if it is, I can't find the citation: https://docs.hhvm.com/hhvm/configuration/INI-settings#php-7-settings |
@jwatzman : this is runtime, not the typechecker |
Yeah looks like I misunderstood your question, ignore my comment above :-P I remember there being some discussion on internal functions and type enforcement. Unfortunately I don't remember if it was in the context of PHP7, Hack types, or even a discussion on internals itself about PHP7's behaviour. While HHVM's behaviour is different than PHP7, it's just a warning -- doesn't strict mode mean that it would throw some sort of exception? The difference seems to be that HHVM has a type annotation on an internal function and PHP7 does not. Maybe we should fix My recollection of how all of this fits together is super rusty, please correct anything above that sounds wrong. Also cc @paulbiss who implemented this for HHVM. |
Including @paulbiss per recommendation. Here are some more samples, same rtrim(null) as above, but similar behavior occurs in other string functions such as substr(). PHP7.0.4 HHVM-nightly hhvm.php7.all = 1 PHP7 declare(strict_types=1) HHVM hhvm.php7.all = 1 declare(strict_types=1) The potential issue is some frameworks/unit tests (Composer is an this case: https://getcomposer.org) catch the warning from rtrim in HHVM's php7.all=1 mode above as a fatal error/incompatiblity. I don't know if true PHP7 compatibility is the goal, of if this should be a documented difference. |
From the Scalar Type Declarations RFC (emphasis added):
So if HHVM does apply the PHP7 weak type checking rules to built-in functions, for PHP7 compatibility, each and every parameter of a built-in function having a scalar type hint (to match zend_parse_parameters()) must accept NULL (unlike user-defined functions), EXCEPT in
|
This is not merely a warning that PHP7 does not generate, yet HHVM does. Rather, the function call fails because of the type error:
In PHP7, I get the same result in both cases:
|
HHVM enables |
Thanks - so it sounds like this is by design. If that's the case and desired, then I would suggest documenting (or at least point to) that HHVM's PHP7 is always/really PHP7 strict_types and isn't targeting default compatibility with PHP7's default “coercive mode”. That would hopefully assist with putting issues to rest about 3rd party code that consider HHVM's PHP7 as "broken" because the code doesn't work in strict_types. |
Is that true? If so, I would expect lines 4 and 5 of the following test case to generate warnings. Instead, only line 5 generates a warning. (In PHP7, no warning or error is generated.)
Also, changing line 2 (the blank line) to read |
I don't know about str_pad in particular, but feel free to test my example of using rtrim(null) above for the behavior I'm seeing. |
rtrim is the same:
Actual result in PHP7:
Changing line 2 to Actual result in HHVM, with
Changing line 2 to Actual result in PHP7, with line 2 changed to
Actual result in HHVM, with
Note the following:
|
OK, got it. So guess the guess the question is in HHVM's PHP7 mode with declare(strict_types=0), is the absence of the special case for built-in's (str_pad, rtrim, etc) to accept NULL for a strings and integers by design or accident? |
So the current behavior is definitely wrong. There are a number of issues with the way that we handle types on builtins. Right now for builtins HHVM will follow the correct PHP7 behavior for declare(strict_types=1), but falls back to PHP5 behavior for declare(strict_types=0) (hence the warning rather than a fatal). The fix for this shouldn't be overly complicated, should just require some updates to tv-helpers.cpp and native.cpp. Will try to give it a look this week. |
Related Error Fatal error: Uncaught TypeError: Argument 1 passed to unserialize() must be an instance of string, null given in /home/travis/.phpenv/versions/hhvm-stable/bin/composer:23
Stack trace:
#0 (): unserialize()
#1 (): __SystemLib\PharArchiveHandler->parsePhar()
#2 (): __SystemLib\PharArchiveHandler->__construct()
#3 (): Phar->__construct()
#4 /home/travis/.phpenv/versions/hhvm-stable/bin/composer(23): Phar::mapPhar()
#5 {main} |
|
@paulbiss Is there any progress on this issue? It would be nice to be able to resume testing against hhvm in php7 mode and this is a blocking issue. |
related error Warning: ini_get_all() expects parameter 1 to be string, null given in /phpunit/src/Util/GlobalState.php on line 79
#0 PHPUnit_Util_GlobalState::getIniSettingsAsString(), called at [/phpunit/src/Framework/TestCase.php:809]
#1 PHPUnit_Framework_TestCase->run(), called at [/phpunit/src/Framework/TestSuite.php:753]
#2 PHPUnit_Framework_TestSuite->run(), called at [/phpunit/src/Framework/TestSuite.php:753]
#3 PHPUnit_Framework_TestSuite->run(), called at [/phpunit/src/Framework/TestSuite.php:753]
#4 PHPUnit_Framework_TestSuite->run(), called at [/phpunit/src/TextUI/TestRunner.php:465]
#5 PHPUnit_TextUI_TestRunner->doRun(), called at [/phpunit/src/TextUI/Command.php:185]
#6 PHPUnit_TextUI_Command->run(), called at [/phpunit/src/TextUI/Command.php:115]
#7 PHPUnit_TextUI_Command::main(), called at [/phpunit/phpunit:47] |
Looks like another couple of projects have dropped HHVM. Breaks like this issue are one of the reasons |
We depend on HHVM and also a lot of open-source code, so this is really bad/stressful for us. Is there anything we can do to vote for this or otherwise support this? |
Hi folks! First off, sorry that the communication on this issue has been a bit choppy and less than upfront. We're going to be meeting very soon to discuss how to prioritize PHP7 compat issues, this one being the biggest of the bunch. I'll try to update here early next week about when we expect we'll be able to get this fixed (it sounds like this is the main remaining incompatibility). As @aorenste mentioned, we had an almost-working patch for the fix, but it's been stuck in rebase hell for a while. That's on us (obviously), and I'm hoping we'll be able to get it sorted out for you all soon. Thanks for your patience, to everyone who's been sticking it out. |
This needed to have been a priority for the past year since the original issue was reported. Just yesterday @mofarrell noted in symfony/symfony#22733 (comment) that:
This leaves me particularly confused about the weight being given to this issue, as well as the intended public perception and expectation you are trying to convey. As this issue makes it impossible to properly support PHP7-mode code in combination with HHVM, this must be prioritized if there is any expectation for library authors to support HHVM. Since many of the projects I help maintain require Symfony components, they too will be dropping support due to the recent decision to drop HHVM support in Symfony's upcoming version I really do appreciate your work, and I also understand that this is a complex issue, but this is causing warranted frustration by many. |
It's a very sad thing that because of the lack of attention to such issues major frameworks just drop HHVM compatibility. Below is a quote from Fabien's post about Symfony 4.0
|
And another has dropped support Joomla is now out. |
Also phpList 4 and Emogrifier: phpList/core#45 MyIntervals/emogrifier#386 |
I think I remember pointing out, before HHVM implemented this, that it would need to handle null differently here. I guess that was overlooked. |
Thanks @mofarrell for pushing a fix for this. With the fix merged, What versions will be getting it? Will all of the current LTS versions be fixed? |
This is probably too intrusive a change for LTS backporting: it's much more important that 3.x.y can run code that 3.x.(y-1) could than for 3.x.y to be able to run /more/ code, even if the code running on 3.x.(y-1) was 'wrong' in some way. Exceptions are rare, except for security fixes. |
The was a insurmountable language bug that caused a divergence between HHVM's internal function type handling from that of PHP's; it should be back-ported IMHO. If it isn't back-ported to the latest LTS it won't be natively available on any distribution until their next LTS release, which will cause more project to abandon HHVM. It's an important fix that would ease concern from the PHP community and hopefully allow you to win back some support. Again, it should be back-ported. |
@fredemmott My understanding is that we do have plans to backport it to at least the current LTS. |
If you're reasonably confident that this won't break existing code written to run on HHVM, I don't mind this being backported. Regardless of the type of bug, unless there's a security issue that makes code changes required, upgrading from 3.x.y to 3.x.(y+1) should never break code that is already running. If it does, that breaks the entire purpose of having LTS releases (and to a lesser extent, .y releases in general). |
If this does end up in 3.18, can you also make sure it ends up in 3.19/3.20? It'd be rather strange to have things work in 3.18 but not 3.19, and will make version constraints that much more annoying. |
The general problem was fixed, but composer isn't; repro case for that issue: https://3v4l.org/ahpE3 (based on @photodude's comment above) |
Filed #7869 for composer as the original issue here is fixed; working on the splfileinfo issue, and whatever else comes up when testing composer. |
Also broken if |
yeah, we differ on any non-string input to splfileinfo |
This issue is needed, because *WE ARE NOT IN A PHP5 WORLD ANY LONGER. The HHVM team, and Facebook Corp., need to be galvanized to committing to stay compatible with PHP7 or they need to break all pretenses and start marking Hack Language as its own thing. Otherwise, once all PHP5 code is collecting dust, relatively soon, all of your, my, and their HHVM efforts will have been in vain! Hopefully this PR is a wakeup call! |
@hopeseekr PHP 5.6 is EOL the same month as PHP 7.0 at the end of 2018. I agree primary efforts should be on compatibility issues with PHP 7.1 and with the alpha/beta release of PHP 7.2. the majority of new development in PHP land has moved to just PHP 7+ support, I agree HHVM needs to make more effort to do the same. |
Summary: Closes #7198 Reviewed By: paulbiss Differential Revision: D4201632 fbshipit-source-id: ca1e253131158c406bf328d2a0dcaa833ac597a4
…tc aren't backported to a Travis-supported version
What is the expected behavior with regards to strict type checking? PHP7 defaults to “coercive mode” while hhvm.php7.all = 1 appears to act like "strict mode" in this example?
HHVM Version
HHVM 3.14.1 hhvm.php7.all = 1
PHP 7.0.4
Standalone code, or other way to reproduce the problem
Expected result
identical (no output)
Actual result
php7 test.php
Potential Solutions
Perhaps hhvm.php7.scalar_types should be left out of hhvm.php7.all? It appears currently to make HHVM act like PHP7's
declare(strict_types=1);
mode.The text was updated successfully, but these errors were encountered: