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

Closed
apeabody opened this Issue Jul 1, 2016 · 61 comments

Comments

Projects
None yet
@apeabody
Contributor

apeabody commented Jul 1, 2016

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

<?php

$result = rtrim(null);
echo $result;

Expected result

identical (no output)

Actual result

hhvm --php test.php

Warning: rtrim() expects parameter 1 to be string, null given in /home/vagrant/hhvm/hphp/test.php on line 3

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.

@jwatzman

This comment has been minimized.

Show comment
Hide comment
@jwatzman

jwatzman Jul 1, 2016

Member

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 hhvm.php7.all = 0.

Member

jwatzman commented Jul 1, 2016

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 hhvm.php7.all = 0.

@apeabody

This comment has been minimized.

Show comment
Hide comment
@apeabody

apeabody Jul 1, 2016

Contributor

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:

hhvm.php7.all = 1
hhvm.php7.scalar_types = 0

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

Contributor

apeabody commented Jul 1, 2016

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:

hhvm.php7.all = 1
hhvm.php7.scalar_types = 0

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

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott Jul 1, 2016

Contributor

@jwatzman : this is runtime, not the typechecker

Contributor

fredemmott commented Jul 1, 2016

@jwatzman : this is runtime, not the typechecker

@apeabody apeabody changed the title from QUESTION: PHP7 vs HHVM PHP7 type checking behavior to QUESTION: PHP7 vs HHVM PHP7 behavior Jul 1, 2016

@jwatzman

This comment has been minimized.

Show comment
Hide comment
@jwatzman

jwatzman Jul 3, 2016

Member

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 rtrim to accept null (eww though).

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.

Member

jwatzman commented Jul 3, 2016

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 rtrim to accept null (eww though).

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.

@jwatzman jwatzman changed the title from QUESTION: PHP7 vs HHVM PHP7 behavior to HHVM and PHP7 differ on type annotations on internal functions (rtrim in particular) Jul 3, 2016

@apeabody

This comment has been minimized.

Show comment
Hide comment
@apeabody

apeabody Jul 5, 2016

Contributor

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
(no warning)

HHVM-nightly hhvm.php7.all = 1
Warning: rtrim() expects parameter 1 to be string, null given in /home/ubuntu/test.php on line 3

PHP7 declare(strict_types=1)
PHP Fatal error: strict_types declaration must not use block mode in /home/ubuntu/test.php on line 2

HHVM hhvm.php7.all = 1 declare(strict_types=1)
Fatal error: Uncaught Error: strict_types declaration must not use block mode in /home/ubuntu/test.php:2
Stack trace:
#0 {main}

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.

Contributor

apeabody commented Jul 5, 2016

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
(no warning)

HHVM-nightly hhvm.php7.all = 1
Warning: rtrim() expects parameter 1 to be string, null given in /home/ubuntu/test.php on line 3

PHP7 declare(strict_types=1)
PHP Fatal error: strict_types declaration must not use block mode in /home/ubuntu/test.php on line 2

HHVM hhvm.php7.all = 1 declare(strict_types=1)
Fatal error: Uncaught Error: strict_types declaration must not use block mode in /home/ubuntu/test.php:2
Stack trace:
#0 {main}

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.

@plstand

This comment has been minimized.

Show comment
Hide comment
@plstand

plstand Aug 2, 2016

From the Scalar Type Declarations RFC (emphasis added):

The weak type checking rules for the new scalar type declarations are mostly the same as those of extension and built-in PHP functions. The only exception to this is the handling of NULL: in order to be consistent with our existing type declarations for classes, callables and arrays, NULL is not accepted by default, unless it is a parameter and is explicitly given a default value of NULL.

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 strict_types mode:

The strict type checking rules are quite straightforward: when the type of the value matches that specified by the type declaration it is accepted, otherwise it is not.

These strict type checking rules are used for userland scalar type declarations, and for extension and built-in PHP functions.

The one exception is that widening primitive conversion is allowed for int to float. This means that parameters that declare float can also accept int.

plstand commented Aug 2, 2016

From the Scalar Type Declarations RFC (emphasis added):

The weak type checking rules for the new scalar type declarations are mostly the same as those of extension and built-in PHP functions. The only exception to this is the handling of NULL: in order to be consistent with our existing type declarations for classes, callables and arrays, NULL is not accepted by default, unless it is a parameter and is explicitly given a default value of NULL.

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 strict_types mode:

The strict type checking rules are quite straightforward: when the type of the value matches that specified by the type declaration it is accepted, otherwise it is not.

These strict type checking rules are used for userland scalar type declarations, and for extension and built-in PHP functions.

The one exception is that widening primitive conversion is allowed for int to float. This means that parameters that declare float can also accept int.

@plstand

This comment has been minimized.

Show comment
Hide comment
@plstand

plstand Aug 2, 2016

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.

This is not merely a warning that PHP7 does not generate, yet HHVM does. Rather, the function call fails because of the type error:

hphpd> =str_pad('', 8)
=str_pad('', 8)
"        "
hphpd> =str_pad(null, 8)
=str_pad(null, 8)

Warning: str_pad() expects parameter 1 to be string, null given
null

In PHP7, I get the same result in both cases:

php > var_dump(str_pad('', 8));
string(8) "        "
php > var_dump(str_pad(null, 8));
string(8) "        "

plstand commented Aug 2, 2016

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.

This is not merely a warning that PHP7 does not generate, yet HHVM does. Rather, the function call fails because of the type error:

hphpd> =str_pad('', 8)
=str_pad('', 8)
"        "
hphpd> =str_pad(null, 8)
=str_pad(null, 8)

Warning: str_pad() expects parameter 1 to be string, null given
null

In PHP7, I get the same result in both cases:

php > var_dump(str_pad('', 8));
string(8) "        "
php > var_dump(str_pad(null, 8));
string(8) "        "
@Orvid

This comment has been minimized.

Show comment
Hide comment
@Orvid

Orvid Aug 2, 2016

Contributor

HHVM enables strict_types by default when you enable php7 mode.

Contributor

Orvid commented Aug 2, 2016

HHVM enables strict_types by default when you enable php7 mode.

@apeabody

This comment has been minimized.

Show comment
Hide comment
@apeabody

apeabody Aug 2, 2016

Contributor

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.

Contributor

apeabody commented Aug 2, 2016

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.

@plstand

This comment has been minimized.

Show comment
Hide comment
@plstand

plstand Aug 2, 2016

HHVM enables strict_types by default.

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.)

<?php

var_dump(str_pad('', 8));
var_dump(str_pad(1, 8));
var_dump(str_pad(null, 8));

Also, changing line 2 (the blank line) to read declare(strict_types=0); makes no difference, and changing it to read declare(strict_types=1); causes line 4 to generate a TypeError, as in PHP7.

plstand commented Aug 2, 2016

HHVM enables strict_types by default.

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.)

<?php

var_dump(str_pad('', 8));
var_dump(str_pad(1, 8));
var_dump(str_pad(null, 8));

Also, changing line 2 (the blank line) to read declare(strict_types=0); makes no difference, and changing it to read declare(strict_types=1); causes line 4 to generate a TypeError, as in PHP7.

@apeabody

This comment has been minimized.

Show comment
Hide comment
@apeabody

apeabody Aug 2, 2016

Contributor

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.

Contributor

apeabody commented Aug 2, 2016

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.

@plstand

This comment has been minimized.

Show comment
Hide comment
@plstand

plstand Aug 2, 2016

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:

<?php

var_dump(rtrim(''));
var_dump(rtrim(1));
var_dump(rtrim(null));

Actual result in PHP7:

string(0) ""
string(1) "1"
string(0) ""

Changing line 2 to declare(strict_types=0); makes no difference.

Actual result in HHVM, with hhvm.php7.all on:

string(0) ""
string(1) "1"

Warning: rtrim() expects parameter 1 to be string, null given in /home/ki/Projects/hhvm/ttt3.php on line 5
NULL

Changing line 2 to declare(strict_types=0); makes no difference.


Actual result in PHP7, with line 2 changed to declare(strict_types=1);:

string(0) ""

Fatal error: Uncaught TypeError: rtrim() expects parameter 1 to be string, integer given in /home/ki/Projects/hhvm/ttt3.php:4
Stack trace:
#0 /home/ki/Projects/hhvm/ttt3.php(4): rtrim(1)
#1 {main}
  thrown in /home/ki/Projects/hhvm/ttt3.php on line 4

Actual result in HHVM, with hhvm.php7.all on, and with line 2 changed to declare(strict_types=1);:

string(0) ""

Fatal error: Uncaught TypeError: Argument 1 passed to rtrim() must be an instance of string, int given in /home/ki/Projects/hhvm/ttt3.php:4
Stack trace:
#0 /home/ki/Projects/hhvm/ttt3.php(4): rtrim()
#1 {main}

Note the following:

  1. With declare(strict_types=1);, HHVM is consistent with PHP7, in that line 4, which passes an integer, throws a TypeError.
  2. With declare(strict_types=0); (the default), PHP7 accepts the string, the integer, and NULL. If the function were a user-defined function, NULL would not have been accepted (by either PHP7 or HHVM), and a TypeError would have been generated.
  3. With declare(strict_types=0); (the default), HHVM accepts the string and the integer, but not NULL. Essentially, HHVM treats the built-in function like a user-defined function, whereas in PHP7, built-in functions are a special case, and NULL is accepted. For scalar (int, float, string, or bool) parameters to user-defined functions, neither PHP7 nor HHVM accept NULL. (Built-in functions are also a special case in that warnings are generated rather than TypeErrors.)

plstand commented Aug 2, 2016

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:

<?php

var_dump(rtrim(''));
var_dump(rtrim(1));
var_dump(rtrim(null));

Actual result in PHP7:

string(0) ""
string(1) "1"
string(0) ""

Changing line 2 to declare(strict_types=0); makes no difference.

Actual result in HHVM, with hhvm.php7.all on:

string(0) ""
string(1) "1"

Warning: rtrim() expects parameter 1 to be string, null given in /home/ki/Projects/hhvm/ttt3.php on line 5
NULL

Changing line 2 to declare(strict_types=0); makes no difference.


Actual result in PHP7, with line 2 changed to declare(strict_types=1);:

string(0) ""

Fatal error: Uncaught TypeError: rtrim() expects parameter 1 to be string, integer given in /home/ki/Projects/hhvm/ttt3.php:4
Stack trace:
#0 /home/ki/Projects/hhvm/ttt3.php(4): rtrim(1)
#1 {main}
  thrown in /home/ki/Projects/hhvm/ttt3.php on line 4

Actual result in HHVM, with hhvm.php7.all on, and with line 2 changed to declare(strict_types=1);:

string(0) ""

Fatal error: Uncaught TypeError: Argument 1 passed to rtrim() must be an instance of string, int given in /home/ki/Projects/hhvm/ttt3.php:4
Stack trace:
#0 /home/ki/Projects/hhvm/ttt3.php(4): rtrim()
#1 {main}

Note the following:

  1. With declare(strict_types=1);, HHVM is consistent with PHP7, in that line 4, which passes an integer, throws a TypeError.
  2. With declare(strict_types=0); (the default), PHP7 accepts the string, the integer, and NULL. If the function were a user-defined function, NULL would not have been accepted (by either PHP7 or HHVM), and a TypeError would have been generated.
  3. With declare(strict_types=0); (the default), HHVM accepts the string and the integer, but not NULL. Essentially, HHVM treats the built-in function like a user-defined function, whereas in PHP7, built-in functions are a special case, and NULL is accepted. For scalar (int, float, string, or bool) parameters to user-defined functions, neither PHP7 nor HHVM accept NULL. (Built-in functions are also a special case in that warnings are generated rather than TypeErrors.)
@apeabody

This comment has been minimized.

Show comment
Hide comment
@apeabody

apeabody Aug 2, 2016

Contributor

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?

Contributor

apeabody commented Aug 2, 2016

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?

@paulbiss

This comment has been minimized.

Show comment
Hide comment
@paulbiss

paulbiss Aug 3, 2016

Contributor

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.

Contributor

paulbiss commented Aug 3, 2016

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.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude Sep 9, 2016

Contributor

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}

https://3v4l.org/lHviH

Contributor

photodude commented Sep 9, 2016

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}

https://3v4l.org/lHviH

@iangcarroll

This comment has been minimized.

Show comment
Hide comment
@iangcarroll

iangcarroll Sep 28, 2016

rtrim not taking null breaks Composer, FYI.

iangcarroll commented Sep 28, 2016

rtrim not taking null breaks Composer, FYI.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude Oct 5, 2016

Contributor

@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.

Contributor

photodude commented Oct 5, 2016

@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.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude Oct 6, 2016

Contributor

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]

https://3v4l.org/s3QtO

Contributor

photodude commented Oct 6, 2016

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]

https://3v4l.org/s3QtO

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude Nov 4, 2016

Contributor

@paulbiss Just checking back on this issue? It would be nice to be able to resume testing against hhvm in php7 mode and this is a blocking issue.

Contributor

photodude commented Nov 4, 2016

@paulbiss Just checking back on this issue? It would be nice to be able to resume testing against hhvm in php7 mode and this is a blocking issue.

@Kazanir

This comment has been minimized.

Show comment
Hide comment
@Kazanir

Kazanir Nov 6, 2016

Right now this issue means that no one can use HHVM to build a Composer project which contains PHP7-only packages, FYI.

Kazanir commented Nov 6, 2016

Right now this issue means that no one can use HHVM to build a Composer project which contains PHP7-only packages, FYI.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude Dec 13, 2016

Contributor

@aorenste Just checking back on this issue....
It would be nice to be able to resume testing against hhvm in php7 mode and this is a blocking issue since it breaks most composer based builds.

Contributor

photodude commented Dec 13, 2016

@aorenste Just checking back on this issue....
It would be nice to be able to resume testing against hhvm in php7 mode and this is a blocking issue since it breaks most composer based builds.

@Orvid

This comment has been minimized.

Show comment
Hide comment
@Orvid

Orvid Dec 13, 2016

Contributor

We have a mostly functional diff up internally to deal with correctly enabling compliance with PHP7 strict mode, but there are still a few edge cases left to solve.

Contributor

Orvid commented Dec 13, 2016

We have a mostly functional diff up internally to deal with correctly enabling compliance with PHP7 strict mode, but there are still a few edge cases left to solve.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude May 4, 2017

Contributor

@SCIF I'm just an interested party in the solution. I have no knowledge on the current progress.

@fredemmott Who is assigned to this issue now that you unassigned @aorenste ? This is a major blocking issue for any project that has moved on to only supporting php 7 and uses composer. (it's also another reason that major projects are or have dropped HHVM support)

Contributor

photodude commented May 4, 2017

@SCIF I'm just an interested party in the solution. I have no knowledge on the current progress.

@fredemmott Who is assigned to this issue now that you unassigned @aorenste ? This is a major blocking issue for any project that has moved on to only supporting php 7 and uses composer. (it's also another reason that major projects are or have dropped HHVM support)

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott May 4, 2017

Contributor

No one is actively working on this as far as I'm aware - I'm no longer working on HHVM though.

Contributor

fredemmott commented May 4, 2017

No one is actively working on this as far as I'm aware - I'm no longer working on HHVM though.

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott May 4, 2017

Contributor

I unassigned Aaron as I believe he's no longer working on compatibility issues; having it in the unassigned pile is better than having it incorrectly marked as being worked on.

Contributor

fredemmott commented May 4, 2017

I unassigned Aaron as I believe he's no longer working on compatibility issues; having it in the unassigned pile is better than having it incorrectly marked as being worked on.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude May 4, 2017

Contributor

If unassigned at the moment is best, then that is best. This is a long standing issue that needs to be addressed to continue php support in hhvm. More php projects will likely drop HHVM support the longer this issue continues to not be addressed.

Contributor

photodude commented May 4, 2017

If unassigned at the moment is best, then that is best. This is a long standing issue that needs to be addressed to continue php support in hhvm. More php projects will likely drop HHVM support the longer this issue continues to not be addressed.

@Orvid

This comment has been minimized.

Show comment
Hide comment
@Orvid

Orvid May 4, 2017

Contributor

@aorenste Would you be willing to at least put the change up as a PR rather than a diff so anyone externally that wants to try to get things working has a decent idea of the scope and where to start?

Contributor

Orvid commented May 4, 2017

@aorenste Would you be willing to at least put the change up as a PR rather than a diff so anyone externally that wants to try to get things working has a decent idea of the scope and where to start?

@aorenste

This comment has been minimized.

Show comment
Hide comment
@aorenste

aorenste May 5, 2017

Contributor

@Orvid The problem is that @paulbiss pointed out that the approach I took isn't even close because it fails if the called function is inlined. As such I'm not sure that my starting point would help someone else. I never got very far on the alternative approach.

Contributor

aorenste commented May 5, 2017

@Orvid The problem is that @paulbiss pointed out that the approach I took isn't even close because it fails if the called function is inlined. As such I'm not sure that my starting point would help someone else. I never got very far on the alternative approach.

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott May 5, 2017

Contributor

dirname() completely breaks composer (https://gist.github.com/fredemmott/783596a9591f19d34940c223dc75dd5b)

given that the PHP ecosystem is rapidly moving on from PHP5, this is really a big deal.

Contributor

fredemmott commented May 5, 2017

dirname() completely breaks composer (https://gist.github.com/fredemmott/783596a9591f19d34940c223dc75dd5b)

given that the PHP ecosystem is rapidly moving on from PHP5, this is really a big deal.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude May 6, 2017

Contributor

@fredemmott I have also seen that, it comes back to the rtrim issue

Fatal error: Uncaught TypeError: Argument 1 passed to dirname() must be an instance of string, bool given in phar://composer.phar/bin/../src/../vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php:141

the root of this from composer to symfony/finder comes from HHVM itself. The dirname call is not in the symfony/finder code, but in the implementation of SplFileInfo->getPath(), which is part of HHVM.
see https://github.com/facebook/hhvm/blob/master/hphp/system/php/spl/file_handling/SplFileInfo.php#L40

digging deeper we are back to the rtrim issue at the class construct call to this method
https://github.com/facebook/hhvm/blob/master/hphp/system/php/spl/file_handling/SplFileInfo.php#L438-L443

related issues

Contributor

photodude commented May 6, 2017

@fredemmott I have also seen that, it comes back to the rtrim issue

Fatal error: Uncaught TypeError: Argument 1 passed to dirname() must be an instance of string, bool given in phar://composer.phar/bin/../src/../vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php:141

the root of this from composer to symfony/finder comes from HHVM itself. The dirname call is not in the symfony/finder code, but in the implementation of SplFileInfo->getPath(), which is part of HHVM.
see https://github.com/facebook/hhvm/blob/master/hphp/system/php/spl/file_handling/SplFileInfo.php#L40

digging deeper we are back to the rtrim issue at the class construct call to this method
https://github.com/facebook/hhvm/blob/master/hphp/system/php/spl/file_handling/SplFileInfo.php#L438-L443

related issues

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude May 18, 2017

Contributor

Looks like another couple of projects have dropped HHVM. Breaks like this issue are one of the reasons

Contributor

photodude commented May 18, 2017

Looks like another couple of projects have dropped HHVM. Breaks like this issue are one of the reasons

@asuth

This comment has been minimized.

Show comment
Hide comment
@asuth

asuth May 18, 2017

Contributor

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?

Contributor

asuth commented May 18, 2017

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?

@mxw

This comment has been minimized.

Show comment
Hide comment
@mxw

mxw May 19, 2017

Contributor

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.

Contributor

mxw commented May 19, 2017

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.

@robfrawley

This comment has been minimized.

Show comment
Hide comment
@robfrawley

robfrawley May 20, 2017

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:

It happens to not be trivial to fix, and also currently not at the top of our priority list.

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 4.x releases. For example, the liip/imagine-bundle package removed HHVM support from the 2.x development branch two weeks ago, as discussed in liip/LiipImagineBundle#908 (comment).

I really do appreciate your work, and I also understand that this is a complex issue, but this is causing warranted frustration by many.

robfrawley commented May 20, 2017

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:

It happens to not be trivial to fix, and also currently not at the top of our priority list.

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 4.x releases. For example, the liip/imagine-bundle package removed HHVM support from the 2.x development branch two weeks ago, as discussed in liip/LiipImagineBundle#908 (comment).

I really do appreciate your work, and I also understand that this is a complex issue, but this is causing warranted frustration by many.

@FractalizeR

This comment has been minimized.

Show comment
Hide comment
@FractalizeR

FractalizeR May 23, 2017

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

Symfony is not the first PHP project to drop HHVM support. Doctrine, CakePHP, and MongoDB dropped or will soon drop HHVM support (as commented on the Twitter poll). Laravel also dropped support as of version 5.3 (released 9 months ago). I can imagine that more PHP libraries will drop support as they will face the same issues as Symfony when requiring PHP 7.

That's also why I have decided to drop HHVM support for all my other significant projects like Twig (as of version 2), Silex, and Swiftmailer.

FractalizeR commented May 23, 2017

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

Symfony is not the first PHP project to drop HHVM support. Doctrine, CakePHP, and MongoDB dropped or will soon drop HHVM support (as commented on the Twitter poll). Laravel also dropped support as of version 5.3 (released 9 months ago). I can imagine that more PHP libraries will drop support as they will face the same issues as Symfony when requiring PHP 7.

That's also why I have decided to drop HHVM support for all my other significant projects like Twig (as of version 2), Silex, and Swiftmailer.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude May 26, 2017

Contributor

And another has dropped support Joomla is now out.
joomla/joomla-cms#16232

Contributor

photodude commented May 26, 2017

And another has dropped support Joomla is now out.
joomla/joomla-cms#16232

@oliverklee

This comment has been minimized.

Show comment
Hide comment
@oliverklee

oliverklee commented May 26, 2017

Also phpList 4 and Emogrifier: phpList/core#45 MyIntervals/emogrifier#386

@hikari-no-yume

This comment has been minimized.

Show comment
Hide comment
@hikari-no-yume

hikari-no-yume May 27, 2017

I think I remember pointing out, before HHVM implemented this, that it would need to handle null differently here. I guess that was overlooked.

hikari-no-yume commented May 27, 2017

I think I remember pointing out, before HHVM implemented this, that it would need to handle null differently here. I guess that was overlooked.

@hhvm-bot hhvm-bot closed this in f02a287 Jun 1, 2017

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude Jun 1, 2017

Contributor

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?

Contributor

photodude commented Jun 1, 2017

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?

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott Jun 1, 2017

Contributor

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.

Contributor

fredemmott commented Jun 1, 2017

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.

@robfrawley

This comment has been minimized.

Show comment
Hide comment
@robfrawley

robfrawley Jun 1, 2017

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.

robfrawley commented Jun 1, 2017

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.

@Orvid

This comment has been minimized.

Show comment
Hide comment
@Orvid

Orvid Jun 1, 2017

Contributor

@fredemmott My understanding is that we do have plans to backport it to at least the current LTS.

Contributor

Orvid commented Jun 1, 2017

@fredemmott My understanding is that we do have plans to backport it to at least the current LTS.

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott Jun 1, 2017

Contributor

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).

Contributor

fredemmott commented Jun 1, 2017

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).

@simonwelsh

This comment has been minimized.

Show comment
Hide comment
@simonwelsh

simonwelsh Jun 3, 2017

Contributor

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.

Contributor

simonwelsh commented Jun 3, 2017

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.

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott Jun 6, 2017

Contributor

The general problem was fixed, but composer isn't; repro case for that issue: https://3v4l.org/ahpE3 (based on @photodude's comment above)

Contributor

fredemmott commented Jun 6, 2017

The general problem was fixed, but composer isn't; repro case for that issue: https://3v4l.org/ahpE3 (based on @photodude's comment above)

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott Jun 6, 2017

Contributor

Filed #7869 for composer as the original issue here is fixed; working on the splfileinfo issue, and whatever else comes up when testing composer.

Contributor

fredemmott commented Jun 6, 2017

Filed #7869 for composer as the original issue here is fixed; working on the splfileinfo issue, and whatever else comes up when testing composer.

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude Jun 6, 2017

Contributor

Also broken if null is passed to splfileinfo() resulting in the same rtrim() issue originally reported (since splfileinfo() is dependent on rtrim() as noted above ).
https://3v4l.org/4ljZ8

Contributor

photodude commented Jun 6, 2017

Also broken if null is passed to splfileinfo() resulting in the same rtrim() issue originally reported (since splfileinfo() is dependent on rtrim() as noted above ).
https://3v4l.org/4ljZ8

@fredemmott

This comment has been minimized.

Show comment
Hide comment
@fredemmott

fredemmott Jun 6, 2017

Contributor

yeah, we differ on any non-string input to splfileinfo

Contributor

fredemmott commented Jun 6, 2017

yeah, we differ on any non-string input to splfileinfo

@hopeseekr

This comment has been minimized.

Show comment
Hide comment
@hopeseekr

hopeseekr Jun 9, 2017

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 commented Jun 9, 2017

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!

@photodude

This comment has been minimized.

Show comment
Hide comment
@photodude

photodude Jun 9, 2017

Contributor

@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.

Contributor

photodude commented Jun 9, 2017

@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.

mofarrell added a commit that referenced this issue Jun 9, 2017

PHP7 - Fix php7 weak vs strict types
Summary: Closes #7198

Reviewed By: paulbiss

Differential Revision: D4201632

fbshipit-source-id: ca1e253131158c406bf328d2a0dcaa833ac597a4

dvdoug added a commit to dvdoug/BoxPacker that referenced this issue Aug 13, 2017

Test against HHVM in PHP7 mode through docker as facebook/hhvm#7198 e…
…tc aren't backported to a Travis-supported version
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment