staabm / phpstan-dba

PHPStan based SQL static analysis and type inference for the database access layer
https://staabm.github.io/archive.html#phpstan-dba
MIT License
257 stars 17 forks source link

Internal error: Unexpected expression type iterable<int> #676

Closed mdumoulin closed 6 days ago

mdumoulin commented 1 month ago

I am trying to add phpstan-dba extension on my project and when I am running the analyse command, I get a report of errors like expected, but also the following exception at the end :

 -- ------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Error                                                                                                                                                              
 -- ------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Internal error: Internal error: Unexpected expression type iterable<int> of class                                                                                  
     PHPStan\Type\IterableType while analysing file                                                                                                                     
     /var/www/.../Class.php                     

Installed versions of libraries are :

Here is the trace when running analyse in verbose mode :

     Post the following stack trace to https://github.com/phpstan/phpstan/issues/new?template=Bug_report.yaml:                                                          
     ## /var/www/vendor/staabm/phpstan-dba/src/QueryReflection/QuerySimulation.php(127)                                                                                 
     #0 /var/www/vendor/staabm/phpstan-dba/src/QueryReflection/QueryReflection.php(470):                                                                                
     staabm\PHPStanDba\QueryReflection\QuerySimulation::simulateParamValueType(Object(PHPStan\Type\IterableType),                                                       
     true)                                                                                                                                                              
     #1 /var/www/vendor/staabm/phpstan-dba/src/QueryReflection/QueryReflection.php(438):                                                                                
     staabm\PHPStanDba\QueryReflection\QueryReflection->resolveConstantArray(Object(PHPStan\Type\Constant\ConstantArrayType))                                           
     #2 /var/www/vendor/staabm/phpstan-dba/src/QueryReflection/QueryReflection.php(261):                                                                                
     staabm\PHPStanDba\QueryReflection\QueryReflection->resolveParameters(Object(PHPStan\Type\Constant\ConstantArrayType))                                              
     #3 /var/www/vendor/staabm/phpstan-dba/src/QueryReflection/QueryReflection.php(240):                                                                                
     staabm\PHPStanDba\QueryReflection\QueryReflection->resolvePreparedQueryString(Object(PhpParser\Node\Scalar\String_),                                               
     Object(PHPStan\Type\Constant\ConstantArrayType), Object(PHPStan\Analyser\MutatingScope))                                                                           
     #4 /var/www/vendor/staabm/phpstan-dba/src/DoctrineReflection/DoctrineReflection.php(170):                                                                          
     staabm\PHPStanDba\QueryReflection\QueryReflection->resolvePreparedQueryStrings(Object(PhpParser\Node\Scalar\String_),                                              
     Object(PHPStan\Type\Constant\ConstantArrayType), Object(PHPStan\Analyser\MutatingScope))                                                                           
     #5                                                                                                                                                                 
     /var/www/vendor/staabm/phpstan-dba/src/Extensions/DoctrineConnectionExecuteQueryDynamicReturnTypeExtension.php(79):                                                
     staabm\PHPStanDba\DoctrineReflection\DoctrineReflection->createGenericResult(Object(Generator), 5)                                                                 
     #6                                                                                                                                                                 
     /var/www/vendor/staabm/phpstan-dba/src/Extensions/DoctrineConnectionExecuteQueryDynamicReturnTypeExtension.php(57):                                                
     staabm\PHPStanDba\Extensions\DoctrineConnectionExecuteQueryDynamicReturnTypeExtension->inferType(Object(PhpParser\Node\Scalar\String_),                            
     Object(PhpParser\Node\Expr\Array_), Object(PHPStan\Analyser\MutatingScope))                                                                                        
     #7 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(3749):                                                                       
     staabm\PHPStanDba\Extensions\DoctrineConnectionExecuteQueryDynamicReturnTypeExtension->getTypeFromMethodCall(Object(PHPStan\Reflection\ResolvedMethodReflection),  
     Object(PhpParser\Node\Expr\MethodCall), Object(PHPStan\Analyser\MutatingScope))                                                                                    
     #8 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1467):                                                                       
     PHPStan\Analyser\MutatingScope->methodCallReturnType(Object(PHPStan\Type\ObjectType), 'executeQuery',                                                              
     Object(PhpParser\Node\Expr\MethodCall))                                                                                                                            
     #9 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1473):                                                                       
     PHPStan\Analyser\MutatingScope->PHPStan\Analyser\{closure}()                                                                                                       
     #10 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(596):                                                                       
     PHPStan\Analyser\MutatingScope->resolveType('$this->connecti...', Object(PhpParser\Node\Expr\MethodCall))                                                          
     #11 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1467):                                                                      
     PHPStan\Analyser\MutatingScope->getType(Object(PhpParser\Node\Expr\MethodCall))                                                                                    
     #12 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1473):                                                                      
     PHPStan\Analyser\MutatingScope->PHPStan\Analyser\{closure}()                                                                                                       
     #13 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(596):                                                                       
     PHPStan\Analyser\MutatingScope->resolveType('$this->connecti...', Object(PhpParser\Node\Expr\MethodCall))                                                          
     #14 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Rules/FunctionReturnTypeCheck.php(52):                                                                 
     PHPStan\Analyser\MutatingScope->getType(Object(PhpParser\Node\Expr\MethodCall))                                                                                    
     #15 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Rules/Methods/ReturnTypeRule.php(56):                                                                  
     PHPStan\Rules\FunctionReturnTypeCheck->checkReturnType(Object(PHPStan\Analyser\MutatingScope),                                                                     
     Object(PHPStan\Type\ArrayType), Object(PhpParser\Node\Expr\MethodCall),                                                                                            
     Object(PhpParser\Node\Stmt\Return_), 'Method Shopping...', 'Method Shopping...', 'Method Shopping...',                                                             
     'Method Shopping...', false)                                                                                                                                       
     #16 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(120):                                                                        
     PHPStan\Rules\Methods\ReturnTypeRule->processNode(Object(PhpParser\Node\Stmt\Return_),                                                                             
     Object(PHPStan\Analyser\MutatingScope))                                                                                                                            
     #17 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Node/ClassStatementsGatherer.php(109):                                                                 
     PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Stmt\Return_),                                                                     
     Object(PHPStan\Analyser\MutatingScope))                                                                                                                            
     #18 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(607):                                                                   
     PHPStan\Node\ClassStatementsGatherer->__invoke(Object(PhpParser\Node\Stmt\Return_),                                                                                
     Object(PHPStan\Analyser\MutatingScope))                                                                                                                            
     #19 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(488):                                                                   
     PHPStan\Analyser\NodeScopeResolver::PHPStan\Analyser\{closure}(Object(PhpParser\Node\Stmt\Return_),                                                                
     Object(PHPStan\Analyser\MutatingScope))                                                                                                                            
     #20 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(430):                                                                   
     PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Return_),                                                                           
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                
     #21 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(606):                                                                   
     PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\ClassMethod), Array,                                                               
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                
     #22 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(430):                                                                   
     PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\ClassMethod),                                                                       
     Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer),                                                                              
     Object(PHPStan\Analyser\StatementContext))                                                                                                                         
     #23 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(743):                                                                   
     PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Class_), Array,                                                                    
     Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer),                                                                              
     Object(PHPStan\Analyser\StatementContext))                                                                                                                         
     #24 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(430):                                                                   
     PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Class_),                                                                            
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                
     #25 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(713):                                                                   
     PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array,                                                                
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                
     #26 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(398):                                                                   
     PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_),                                                                        
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                
     #27 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(179):                                                                        
     PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope),                                                                    
     Object(Closure))                                                                                                                                                   
     #28 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(137):                                                                        
     PHPStan\Analyser\FileAnalyser->analyseFile('/var/www/projec...', Array,                                                                                            
     Object(PHPStan\Rules\LazyRegistry), Object(PHPStan\Collectors\Registry), NULL)                                                                                     
     #29                                                                                                                                                                
     phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                                            
     PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}(Array)                                                                                                    
     #30 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(117):                                                             
     _PHPStan_d5a4746e9\Evenement\EventEmitter->emit('data', Array)                                                                                                     
     #31                                                                                                                                                                
     phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                                            
     _PHPStan_d5a4746e9\Clue\React\NDJson\Decoder->handleData(Array)                                                                                                    
     #32 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62):                                                                      
     _PHPStan_d5a4746e9\Evenement\EventEmitter->emit('data', Array)                                                                                                     
     #33                                                                                                                                                                
     phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                                            
     _PHPStan_d5a4746e9\React\Stream\Util::_PHPStan_d5a4746e9\React\Stream\{closure}('{"action":"anal...')                                                              
     #34                                                                                                                                                                
     phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154):                                                         
     _PHPStan_d5a4746e9\Evenement\EventEmitter->emit('data', Array)                                                                                                     
     #35                                                                                                                                                                
     phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201):                                                         
     _PHPStan_d5a4746e9\React\Stream\DuplexResourceStream->handleData(Resource id #11809)                                                                               
     #36                                                                                                                                                                
     phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173):                                                         
     _PHPStan_d5a4746e9\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)                                                                                   
     #37 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(98):                                                                         
     _PHPStan_d5a4746e9\React\EventLoop\StreamSelectLoop->run()                                                                                                         
     #38 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259):                                                           
     PHPStan\Command\WorkerCommand->execute(Object(_PHPStan_d5a4746e9\Symfony\Component\Console\Input\ArgvInput),                                                       
     Object(_PHPStan_d5a4746e9\Symfony\Component\Console\Output\ConsoleOutput))                                                                                         
     #39 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(870):                                                               
     _PHPStan_d5a4746e9\Symfony\Component\Console\Command\Command->run(Object(_PHPStan_d5a4746e9\Symfony\Component\Console\Input\ArgvInput),                            
     Object(_PHPStan_d5a4746e9\Symfony\Component\Console\Output\ConsoleOutput))                                                                                         
     #40 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(261):                                                               
     _PHPStan_d5a4746e9\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\WorkerCommand),                                                      
     Object(_PHPStan_d5a4746e9\Symfony\Component\Console\Input\ArgvInput),                                                                                              
     Object(_PHPStan_d5a4746e9\Symfony\Component\Console\Output\ConsoleOutput))                                                                                         
     #41 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157):                                                               
     _PHPStan_d5a4746e9\Symfony\Component\Console\Application->doRun(Object(_PHPStan_d5a4746e9\Symfony\Component\Console\Input\ArgvInput),                              
     Object(_PHPStan_d5a4746e9\Symfony\Component\Console\Output\ConsoleOutput))                                                                                         
     #42 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(124):                                                                                          
     _PHPStan_d5a4746e9\Symfony\Component\Console\Application->run()                                                                                                    
     #43 phar:///var/www/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(125): _PHPStan_d5a4746e9\{closure}()                                                           
     #44 /var/www/vendor/phpstan/phpstan/phpstan(8): require('phar:///var/www...')                                                                                      
     #45 /var/www/vendor/bin/phpstan(119): include('/var/www/vendor...')                                                                                                
     #46 {main}                                                                                                                                                         
     Child process error (exit code 1):                                                                                                                                 
staabm commented 1 week ago

Could you provide a reproduction example?

mdumoulin commented 6 days ago

If you try to analyse the following class, you should reproduce. Note, there is an inconsistency between iterable $ids and the type documented in Connection::executeQuery() for $queryParams. If you replace iterable by array, the Internal error is no longer triggered.

<?php

namespace Test;

use Doctrine\DBAL\Connection;

class Test
{
    public function __construct(private Connection $connection)
    {

    }

    public function getIds(iterable $ids): array
    {
        return $this
            ->connection
            ->executeQuery(
                'SELECT id FROM table WHERE id IN (:list)',
                ['list' => $ids],
                ['list' => DBAL\Connection::PARAM_INT_ARRAY],
            )
            ->fetchFirstColumn();
    }
}
staabm commented 6 days ago

fixed in https://github.com/staabm/phpstan-dba/pull/693 - released in https://github.com/staabm/phpstan-dba/releases/tag/0.2.84

thanks for the repro