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

PHPStan crashes if Doctrine Column is a UnitEnum (PHPStan+Doctrine extension) #522

Open
Firehed opened this issue Jan 23, 2024 · 2 comments

Comments

@Firehed
Copy link

Firehed commented Jan 23, 2024

Bug report

This indicates an error in my code, but the crash is unexpected. I'm providing the bug report and stack trace as the PHPStan output requests, but through some quick trial-and-error I was able to determine that #[Mapping\Column] on a class property that's unsupported would trigger it.

Not sure if this would happen if Doctrine had a custom type mapper set which allows this to work (seeing the stack trace, it looks like probably), but I think PHPStan, or more specifically the Doctrine extension, should catch the assertion error and translate it into an analysis warning of some kind.

Simple reproduce code:

<?php

declare(strict_types=1);

namespace App\Entities;

use Doctrine\ORM\Mapping;

#[Mapping\Entity]
class Bug
{
    #[Mapping\Column]
    #[Mapping\Id]
    public string $id;

    #[Mapping\Column]
    public Status $status;

    public function causeError(): void
    {
        $this->a = 1; // This should error, instead PHPStan crashes
    }
}

enum Status
{
    case Working;
    case Broken;
}
# $ cat phpstan.neon
includes:
    # phpstan-baseline.neon
    - vendor/phpstan/phpstan-phpunit/extension.neon
    - vendor/phpstan/phpstan-strict-rules/rules.neon
    - vendor/phpstan/phpstan-deprecation-rules/rules.neon
    - vendor/phpstan/phpstan-doctrine/extension.neon
    - vendor/phpstan/phpstan-doctrine/rules.neon
parameters:
    excludePaths:
        - rector.php
        - vendor
    level: max
    paths:
        - .
    universalObjectCratesClasses:
        - Stripe\StripeObject
Internal error: Internal error: assert($type instanceof ReflectionNamedType) while analysing file (...)

     ## (path)/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php(62)
     #0 (path)/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php(62): assert(false, 'assert($type in...')
     phpstan/phpstan#1 (path)/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php(1594): Doctrine\ORM\Mapping\DefaultTypedFieldMapper->validateAndComplete(Array, Object(ReflectionProperty))
     phpstan/phpstan#2 (path)/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php(1644): Doctrine\ORM\Mapping\ClassMetadataInfo->validateAndCompleteTypedFieldMapping(Array)
     phpstan/phpstan#3 (path)/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php(2723): Doctrine\ORM\Mapping\ClassMetadataInfo->validateAndCompleteFieldMapping(Array)
     phpstan/phpstan#4 (path)/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php(369): Doctrine\ORM\Mapping\ClassMetadataInfo->mapField(Array)
     phpstan/phpstan#5 (path)/vendor/phpstan/phpstan-doctrine/src/Doctrine/Mapping/MappingDriverChain.php(31): Doctrine\ORM\Mapping\Driver\AttributeDriver->loadMetadataForClass('App\\Entities\\In...', Object(Doctrine\ORM\Mapping\ClassMetadata))
     phpstan/phpstan#6 (path)/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(149): PHPStan\Doctrine\Mapping\MappingDriverChain->loadMetadataForClass('App\\Entities\\In...', Object(Doctrine\ORM\Mapping\ClassMetadata))
     phpstan/phpstan#7 (path)/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(343): Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL, false, Array)
     phpstan/phpstan#8 (path)/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(225): Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata('App\\Entities\\In...')
     phpstan/phpstan#9 (path)/vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/ObjectMetadataResolver.php(129): Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor('App\\Entities\\In...')
     phpstan/phpstan#10 (path)/vendor/phpstan/phpstan-doctrine/src/Rules/Doctrine/ORM/PropertiesExtension.php(27): PHPStan\Type\Doctrine\ObjectMetadataResolver->getClassMetadata('App\\Entities\\In...')
     phpstan/phpstan#11 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Rules/DeadCode/UnusedPrivatePropertyRule.php(100): PHPStan\Rules\Doctrine\ORM\PropertiesExtension->isAlwaysRead(Object(PHPStan\Reflection\Php\PhpPropertyReflection), 'amount')
     phpstan/phpstan#12 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(107): PHPStan\Rules\DeadCode\UnusedPrivatePropertyRule->processNode(Object(PHPStan\Node\ClassPropertiesNode), Object(PHPStan\Analyser\MutatingScope))
     phpstan/phpstan#13 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(669): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PHPStan\Node\ClassPropertiesNode), Object(PHPStan\Analyser\MutatingScope))
     phpstan/phpstan#14 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(401): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Class_), Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))
     phpstan/phpstan#15 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(640): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure),
     Object(PHPStan\Analyser\StatementContext))
     phpstan/phpstan#16 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(370): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_), Object(PHPStan\Analyser\MutatingScope), Object(Closure),
     Object(PHPStan\Analyser\StatementContext))
     phpstan/phpstan#17 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(166): PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
     phpstan/phpstan#18 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(132): PHPStan\Analyser\FileAnalyser->analyseFile('/Users/firehed/...', Array, Object(PHPStan\Rules\LazyRegistry), Object(PHPStan\Collectors\Registry), NULL)
     phpstan/phpstan#19 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}(Array)
     phpstan/phpstan#20 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(117): _PHPStan_3d4486d07\Evenement\EventEmitter->emit('data', Array)
     phpstan/phpstan#21 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): _PHPStan_3d4486d07\Clue\React\NDJson\Decoder->handleData(Array)
     phpstan/phpstan#22 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62): _PHPStan_3d4486d07\Evenement\EventEmitter->emit('data', Array)
     phpstan/phpstan#23 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): _PHPStan_3d4486d07\React\Stream\Util::_PHPStan_3d4486d07\React\Stream\{closure}('{"action":"anal...')
     phpstan/phpstan#24 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154): _PHPStan_3d4486d07\Evenement\EventEmitter->emit('data', Array)
     phpstan/phpstan#25 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201): _PHPStan_3d4486d07\React\Stream\DuplexResourceStream->handleData(Resource id phpstan/phpstan#6555)
     phpstan/phpstan#26 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173): _PHPStan_3d4486d07\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)
     phpstan/phpstan#27 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(98): _PHPStan_3d4486d07\React\EventLoop\StreamSelectLoop->run()
     phpstan/phpstan#28 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259): PHPStan\Command\WorkerCommand->execute(Object(_PHPStan_3d4486d07\Symfony\Component\Console\Input\ArgvInput),
     Object(_PHPStan_3d4486d07\Symfony\Component\Console\Output\ConsoleOutput))
     phpstan/phpstan#29 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(870): _PHPStan_3d4486d07\Symfony\Component\Console\Command\Command->run(Object(_PHPStan_3d4486d07\Symfony\Component\Console\Input\ArgvInput),
     Object(_PHPStan_3d4486d07\Symfony\Component\Console\Output\ConsoleOutput))
     phpstan/phpstan#30 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(261): _PHPStan_3d4486d07\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\WorkerCommand), Object(_PHPStan_3d4486d07\Symfony\Component\Console\Input\ArgvInput),
     Object(_PHPStan_3d4486d07\Symfony\Component\Console\Output\ConsoleOutput))
     phpstan/phpstan#31 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157): _PHPStan_3d4486d07\Symfony\Component\Console\Application->doRun(Object(_PHPStan_3d4486d07\Symfony\Component\Console\Input\ArgvInput),
     Object(_PHPStan_3d4486d07\Symfony\Component\Console\Output\ConsoleOutput))
     phpstan/phpstan#32 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(124): _PHPStan_3d4486d07\Symfony\Component\Console\Application->run()
     phpstan/phpstan#33 phar://(path)/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(125): _PHPStan_3d4486d07\{closure}()
     phpstan/phpstan#34 (path)/vendor/phpstan/phpstan/phpstan(8): require('phar:///Users/f...')
     phpstan/phpstan#35 (path)/vendor/bin/phpstan(119): include('/Users/firehed/...')
     phpstan/phpstan#36 {main}

Code snippet that reproduces the problem

No response

Expected output

No crash, possibly an indication of an invalid column mapping.

Did PHPStan help you today? Did it make you happy in any way?

No response

Copy link

mergeable bot commented Jan 23, 2024

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

It will most likely be closed after manual review.

@ondrejmirtes ondrejmirtes transferred this issue from phpstan/phpstan Jan 24, 2024
@stof
Copy link
Contributor

stof commented Apr 22, 2024

The crash is actually not in phpstan but in doctrine/orm based on the stack trace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants