Skip to content
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

First-class callable error since PHPStan 1.8.3 #8078

Closed
leofeyer opened this issue Sep 28, 2022 · 17 comments
Closed

First-class callable error since PHPStan 1.8.3 #8078

leofeyer opened this issue Sep 28, 2022 · 17 comments

Comments

@leofeyer
Copy link

leofeyer commented Sep 28, 2022

Bug report

Since PHPStan 1.8.3, we are getting an error when trying to analyze a class with a first-class callable.

Code snippet that reproduces the problem

<?php declare(strict_types = 1);

class HelloWorld
{
	public function test(): void
	{
		$closure = (static fn (): string => 'evaluated Closure')(...);
	}
}

Note that the error is not triggered in the PHPStan playground.

Stack trace

 -- ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Error                                                                                                                                                           
 -- ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Internal error: Internal error: assert(!$this->isFirstClassCallable()) in file /Users/leofeyer/Temp/phpstan/HelloWorld.php                                      
                                                                                                                                                                     
     Post the following stack trace to https://github.com/phpstan/phpstan/issues/new?template=Bug_report.md:                                                         
     #0 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.php(37): assert(false,      
     'assert(!$this->...')                                                                                                                                           
     #1 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/src/Parser/ArrowFunctionArgVisitor.php(15): PhpParser\Node\Expr\CallLike->getArgs()  
     #2 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(113):                        
     PHPStan\Parser\ArrowFunctionArgVisitor->enterNode(Object(PhpParser\Node\Expr\FuncCall))                                                                         
     #3 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(133):                        
     PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Expr\Assign))                                                                                       
     #4 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196):                        
     PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Expression))                                                                                   
     #5 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105):                        
     PhpParser\NodeTraverser->traverseArray(Array)                                                                                                                   
     #6 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196):                        
     PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\ClassMethod))                                                                                  
     #7 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105):                        
     PhpParser\NodeTraverser->traverseArray(Array)                                                                                                                   
     #8 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196):                        
     PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Class_))                                                                                       
     #9 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(85):                         
     PhpParser\NodeTraverser->traverseArray(Array)                                                                                                                   
     #10 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/src/Parser/RichParser.php(77): PhpParser\NodeTraverser->traverse(Array)             
     #11 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/src/Parser/RichParser.php(52): PHPStan\Parser\RichParser->parseString('<?php        
     declare(s...')                                                                                                                                                  
     #12 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/src/Parser/PathRoutingParser.php(61):                                               
     PHPStan\Parser\RichParser->parseFile('/Users/leofeyer...')                                                                                                      
     #13 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/src/Parser/CachedParser.php(44):                                                    
     PHPStan\Parser\PathRoutingParser->parseFile('/Users/leofeyer...')                                                                                               
     #14 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(86):                                                  
     PHPStan\Parser\CachedParser->parseFile('/Users/leofeyer...')                                                                                                    
     #15 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(147):                                                 
     PHPStan\Analyser\FileAnalyser->analyseFile('/Users/leofeyer...', Array, Object(PHPStan\Rules\Registry), Object(PHPStan\Collectors\Registry), NULL)              
     #16 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                 
     PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}(Array)                                                                                                 
     #17 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(110):                                      
     _PHPStan_3bfe2e67c\Evenement\EventEmitter->emit('data', Array)                                                                                                  
     #18 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                 
     _PHPStan_3bfe2e67c\Clue\React\NDJson\Decoder->handleData(Array)                                                                                                 
     #19 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62):                                               
     _PHPStan_3bfe2e67c\Evenement\EventEmitter->emit('data', Array)                                                                                                  
     #20 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                 
     _PHPStan_3bfe2e67c\React\Stream\Util::_PHPStan_3bfe2e67c\React\Stream\{closure}('{"action":"anal...')                                                           
     #21 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154):                              
     _PHPStan_3bfe2e67c\Evenement\EventEmitter->emit('data', Array)                                                                                                  
     #22 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201):                              
     _PHPStan_3bfe2e67c\React\Stream\DuplexResourceStream->handleData(Resource id #3286)                                                                             
     #23 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173):                              
     _PHPStan_3bfe2e67c\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)                                                                                
     #24 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(107):                                                 
     _PHPStan_3bfe2e67c\React\EventLoop\StreamSelectLoop->run()                                                                                                      
     #25 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259):                                    
     PHPStan\Command\WorkerCommand->execute(Object(_PHPStan_3bfe2e67c\Symfony\Component\Console\Input\ArgvInput),                                                    
     Object(_PHPStan_3bfe2e67c\Symfony\Component\Console\Output\ConsoleOutput))                                                                                      
     #26 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(865):                                        
     _PHPStan_3bfe2e67c\Symfony\Component\Console\Command\Command->run(Object(_PHPStan_3bfe2e67c\Symfony\Component\Console\Input\ArgvInput),                         
     Object(_PHPStan_3bfe2e67c\Symfony\Component\Console\Output\ConsoleOutput))                                                                                      
     #27 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(259):                                        
     _PHPStan_3bfe2e67c\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\WorkerCommand),                                                   
     Object(_PHPStan_3bfe2e67c\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_3bfe2e67c\Symfony\Component\Console\Output\ConsoleOutput))                
     #28 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157):                                        
     _PHPStan_3bfe2e67c\Symfony\Component\Console\Application->doRun(Object(_PHPStan_3bfe2e67c\Symfony\Component\Console\Input\ArgvInput),                           
     Object(_PHPStan_3bfe2e67c\Symfony\Component\Console\Output\ConsoleOutput))                                                                                      
     #29 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(124): _PHPStan_3bfe2e67c\Symfony\Component\Console\Application->run()   
     #30 phar:///Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(125): _PHPStan_3bfe2e67c\{closure}()                                    
     #31 /Users/leofeyer/Temp/phpstan/vendor/phpstan/phpstan/phpstan(8): require('phar:///Users/l...')                                                               
     #32 /Users/leofeyer/Temp/phpstan/vendor/bin/phpstan(120): include('/Users/leofeyer...')                                                                         
     #33 {main}                                                                                                                                                      
     Child process error (exit code 1):                                                                                                                              
 -- ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 

It does work with PHPStan 1.8.2, so maybe it is related to phpstan/phpstan-src#1628?

@mergeable
Copy link

mergeable bot commented Sep 28, 2022

This bug report is missing a link to reproduction at phpstan.org/try.

It will most likely be closed after manual review.

@leofeyer
Copy link
Author

As I wrote above, the error is not triggered in the PHPStan playground. 🤷‍♂️

@mad-briller
Copy link
Contributor

mad-briller commented Sep 28, 2022

duplicate of #8072

@leofeyer
Copy link
Author

leofeyer commented Sep 29, 2022

Not sure if that is correct. The error message in #8072 is

Internal error: PHPStan\Analyser\MutatingScope::getType(): Argument #1 ($node) must be of type PhpParser\Node\Expr, null given

but the error message here is

Internal error: Internal error: assert(!$this->isFirstClassCallable()) in file.

@ondrejmirtes
Copy link
Member

@leofeyer I can only fix it with a reproduction. If you can't reproduce it on the playground, please create a small repository where it crashes the same way. Thanks.

@herndlm
Copy link
Contributor

herndlm commented Sep 29, 2022

@leofeyer check my comments there. It kind of explains why the error differs. It should indeed be the same since the error is environment dependent

@leofeyer
Copy link
Author

leofeyer commented Sep 29, 2022

If you can't reproduce it on the playground, please create a small repository where it crashes the same way. Thanks.

Sure: https://github.com/leofeyer/phpstan-8078

Strangely enough, the issue does not occur in the Github Actions runner. However, if I run vendor/bin/phpstan analyze HelloWorld.php -v on my system, the error is thrown. 🤔

Then I guess it is a problem on my system (iMac M1 with macOS 12.6). Sorry for the noise.

@leofeyer leofeyer closed this as not planned Won't fix, can't repro, duplicate, stale Sep 29, 2022
@bytehead
Copy link

I can reproduce the error on my Macbook Pro 16" (M1, macOS 12.6, PHP 8.1.10 (cli) (built: Sep 3 2022 12:09:27) (NTS)) as well.

@leofeyer
Copy link
Author

It seems to be a Mac ARM issue as it does not occur on Windows, Ubuntu and the macos-latest runner on GitHub, which does not yet use the latest hardware (see actions/runner-images#2187).

@herndlm Does it make sense to reopen the issue or do you still think that #8072 will fix it?

@ondrejmirtes
Copy link
Member

I have an ARM Mac and I can reproduce the issue in your repo 🎉

@ondrejmirtes
Copy link
Member

BTW by looking at it I don't think it's OS-specific issue, it's just that PHP has to be configured to throw exceptions on assert() I think.

@leofeyer
Copy link
Author

Ah, good point. 👍

@ondrejmirtes
Copy link
Member

Fixed: phpstan/phpstan-src@6cd3d5d

@bytehead
Copy link

Thank you @ondrejmirtes!

@herndlm
Copy link
Contributor

herndlm commented Sep 29, 2022

👍 yeah the assert behaviour is what I meant with environment specific. The explanation was not good, I'm currently travelling 😅 Great that Ondřej could fix it so fast!

@leofeyer
Copy link
Author

Thank you 🥳

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 31, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants