Page MenuHomePhabricator

Phan now (wrongly) complains about code using variadic parameters
Closed, ResolvedPublic

Description

T228563: Phan rejects variadic calls to BagOStuff::makeKey()

  • Affecting mediawiki/extensions/OATHAuth, mediawiki/extensions/Echo, and others.

T191666: Define varargs in \IContextSource::msg() in a way phan can understand it

  • Affecting mediawiki/extensions/WikiEditor, and others.

T191668: Define varargs in \IDatabase::buildLike() in a way phan can understand it

  • Affecting mediawiki/extensions/Jade, and others.

This used to not be an issue, and the code paths haven't fundamentally changed. I suspect this is the side-effect of a recent Phan upgrade.

Do we still version those globally/centrally, thus unable to verify whether the new version passes existing code and causing build failures?

Can we revert? Or disable the PhanParamTooMany rule wholesale?

Event Timeline

Krinkle triaged this task as High priority.Jul 22 2019, 8:38 PM

I suspect this is the side-effect of a recent Phan upgrade

There hasn't been any recent upgrade, especially for what concerns T228563. Instead, I believe some change in the code made it easier for phan to analyze it more deeply, and thus it discovered this "error".

Globally disabling PhanParamTooMany sounds like an overkill to me, unless -of course- fixing the root cause turns out to be more complicated than expected.

Lastly, I don't really agree with "wrong". For T228563, phan is definitely right. Varargs are not documented, and this is not just a phan problem. It's also for people who know nothing about the BagOStuff classes and read the docs for the first time. They cannot know those methods are variadic, unless they look at the implementation. So IMHO it's good that phan "reminds" us that those docs need updating.
As for the other 2 examples, that seems to be more of a doc-style problem, and TBH I didn't really investigate it.

I'm getting:

11:09:17 Fatal error: Parameter $components is variadic and has a type constraint (array); variadic params with type constraints are not supported in non-Hack files in /workspace/src/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php(290)(620b966bb1c9cc130bb7c31bd1169dca) : eval()'d code on line 473

Is Phan examining the phpunit code? Or am I misreading that error message?

This is blocking a long chain of patches starting at https://gerrit.wikimedia.org/r/c/mediawiki/core/+/532982

I'm getting:

11:09:17 Fatal error: Parameter $components is variadic and has a type constraint (array); variadic params with type constraints are not supported in non-Hack files in /workspace/src/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php(290)(620b966bb1c9cc130bb7c31bd1169dca) : eval()'d code on line 473

Is Phan examining the phpunit code? Or am I misreading that error message?

This is blocking a long chain of patches starting at https://gerrit.wikimedia.org/r/c/mediawiki/core/+/532982

Heh, this is an HHVM +PHPUnit limitation with variadic functions. IIRC, if you have a variadic function and try to mock it, PHPUnit will add a typehint (array), which in turn HHVM cannot handle for variadic parameters.

Heh, this is an HHVM +PHPUnit limitation with variadic functions. IIRC, if you have a variadic function and try to mock it, PHPUnit will add a typehint (array), which in turn HHVM cannot handle for variadic parameters.

So that issue is completely separate from the Phan issue?
Any idea how do I fix that?

Heh, this is an HHVM +PHPUnit limitation with variadic functions. IIRC, if you have a variadic function and try to mock it, PHPUnit will add a typehint (array), which in turn HHVM cannot handle for variadic parameters.

So that issue is completely separate from the Phan issue?

Yes, it's just HHVM's fault. I found a proper explanation at T191668#5263929.

Any idea how do I fix that?

There are various ways... One is to remove the variadic params, but I don't like doing that, especially now that we're closer to dropping HHVM. Another solution is to avoid mocking methods having variadic parameters, but sometimes you have no choice. So, the best solution (adopted e.g. in https://gerrit.wikimedia.org/r/#/c/mediawiki/core/+/524646/) is to mark failing test as skipped if we're running on HHVM. The tests will still run under PHP7, and when the time will come to remove HHVM, they'll be easy to spot thanks to the use of HHVM_VERSION.

There are various ways... One is to remove the variadic params, but I don't like doing that, especially now that we're closer to dropping HHVM. Another solution is to avoid mocking methods having variadic parameters, but sometimes you have no choice. So, the best solution (adopted e.g. in https://gerrit.wikimedia.org/r/#/c/mediawiki/core/+/524646/) is to mark failing test as skipped if we're running on HHVM. The tests will still run under PHP7, and when the time will come to remove HHVM, they'll be easy to spot thanks to the use of HHVM_VERSION.

Will do that, thank you!

Umherirrender subscribed.

Varargs in use and the error suppressions are removed, so this is fixed now.