phpstan: Crash when analyzing files containing DateTimeImmutable typehints with timecop enabled

Bug report

After updating to PHPStan 0.12 every time a file containing the DateTimeImmutable typehint (and probably DateTime too) is analyzed the tool crashes with the error: Internal error: Internal error: Expected to find an ancestor with class name TimecopDateTimeImmutable on DateTimeImmutable, but none was found.. The culprit of the issue is the timecop extension, but it used to work before. Stacktrace is the following:

Exception trace:
  at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Reflection/Php/PhpClassReflectionExtension.php:255
 PHPStan\Reflection\Php\PhpClassReflectionExtension->createMethod() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Reflection/Php/PhpClassReflectionExtension.php:231
 PHPStan\Reflection\Php\PhpClassReflectionExtension->getNativeMethod() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Reflection/ClassReflection.php:267
 PHPStan\Reflection\ClassReflection->getNativeMethod() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Reflection/ClassReflection.php:279
 PHPStan\Reflection\ClassReflection->getConstructor() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/MutatingScope.php:2135
 PHPStan\Analyser\MutatingScope->exactInstantiation() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/MutatingScope.php:748
 PHPStan\Analyser\MutatingScope->resolveType() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/MutatingScope.php:280
 PHPStan\Analyser\MutatingScope->getType() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Reflection/ParametersAcceptorSelector.php:36
 PHPStan\Reflection\ParametersAcceptorSelector::selectFromArgs() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Rules/Classes/InstantiationRule.php:112
 PHPStan\Rules\Classes\InstantiationRule->checkClassName() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Rules/Classes/InstantiationRule.php:45
 PHPStan\Rules\Classes\InstantiationRule->processNode() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/Analyser.php:118
 PHPStan\Analyser\Analyser->PHPStan\Analyser\{closure}() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:297
 PHPStan\Analyser\NodeScopeResolver::PHPStan\Analyser\{closure}() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:1475
 PHPStan\Analyser\NodeScopeResolver->callNodeCallbackWithExpression() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:972
 PHPStan\Analyser\NodeScopeResolver->processExprNode() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:314
 PHPStan\Analyser\NodeScopeResolver->processStmtNode() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:200
 PHPStan\Analyser\NodeScopeResolver->processStmtNodes() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:302
 PHPStan\Analyser\NodeScopeResolver->processStmtNode() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:200
 PHPStan\Analyser\NodeScopeResolver->processStmtNodes() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:359
 PHPStan\Analyser\NodeScopeResolver->processStmtNode() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:200
 PHPStan\Analyser\NodeScopeResolver->processStmtNodes() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:343
 PHPStan\Analyser\NodeScopeResolver->processStmtNode() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/NodeScopeResolver.php:169
 PHPStan\Analyser\NodeScopeResolver->processNodes() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Analyser/Analyser.php:164
 PHPStan\Analyser\Analyser->analyse() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Command/AnalyseApplication.php:99
 PHPStan\Command\AnalyseApplication->analyse() at phar:///srv/vendor/phpstan/phpstan/phpstan/src/Command/AnalyseCommand.php:76
 PHPStan\Command\AnalyseCommand->execute() at phar:///srv/vendor/phpstan/phpstan/phpstan/vendor/symfony/console/Command/Command.php:228
 _HumbugBoxb49a3c9618cf\Symfony\Component\Console\Command\Command->run() at phar:///srv/vendor/phpstan/phpstan/phpstan/vendor/symfony/console/Application.php:858
 _HumbugBoxb49a3c9618cf\Symfony\Component\Console\Application->doRunCommand() at phar:///srv/vendor/phpstan/phpstan/phpstan/vendor/symfony/console/Application.php:236
 _HumbugBoxb49a3c9618cf\Symfony\Component\Console\Application->doRun() at phar:///srv/vendor/phpstan/phpstan/phpstan/vendor/symfony/console/Application.php:137
 _HumbugBoxb49a3c9618cf\Symfony\Component\Console\Application->run() at phar:///srv/vendor/phpstan/phpstan/phpstan/bin/phpstan:51
 _HumbugBoxb49a3c9618cf\{closure}() at phar:///srv/vendor/phpstan/phpstan/phpstan/bin/phpstan:52
 require() at /srv/vendor/phpstan/phpstan/phpstan:6

Code snippet that reproduces the problem

use DateTimeImmutable;

class Foo
{
    public function __construct(DateTimeImmutable $bar)
    {
    }
}

new Foo(new DateTimeImmutable());

Expected output

Parsing of the file is successful.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 19 (13 by maintainers)

Most upvoted comments

Running PHPStan in parallel will not pass -d flags other than memory_limit right now.

There is no need to run PHPStan with the extension disabled, it’s enough to use the INI setting timecop.func_override=0. You can pass it to the CLI like this: php -dtimecop.func_override=0 vendor/bin/phpstan analyse

Are there any possibility to either pass this options to sub-processes

Out of scope of this issue, but indeed helpful, would be to pass all the CLI options (at least the ones that start with -d) to the worker processes because it may be needed to tweak some PHP INI while running PHPStan and this should of course propagate to those processes