-
-
Notifications
You must be signed in to change notification settings - Fork 946
Description
Bug report
I have a problem with the combination of enum and match. As soon as a match arm has multiple expressions and throws an exception as a result, phpstan breaks.
I have tried several combinations. All with phpstan in version 2.1, 1.12.16, 1.12.15
This was my local stacktrace
Internal error: Cannot create PHPStan\Type\UnionType with: 'FooBarEnum', 'FooBarEnum' while analysing file
## phar:///vendor/phpstan/phpstan/phpstan.phar/src/Type/UnionType.php(69)
#0 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Type/UnionType.php(83): PHPStan\Type\UnionType::PHPStan\Type\{closure}()
#1 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Type/Php/GetDebugTypeFunctionReturnTypeExtension.php(31): PHPStan\Type\UnionType->__construct()
#2 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1774):
PHPStan\Type\Php\GetDebugTypeFunctionReturnTypeExtension->getTypeFromFunctionCall()
#3 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(622): PHPStan\Analyser\MutatingScope->resolveType()
#4 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Type/Php/SprintfFunctionDynamicReturnTypeExtension.php(237): PHPStan\Analyser\MutatingScope->getType()
#5 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Type/Php/SprintfFunctionDynamicReturnTypeExtension.php(51):
PHPStan\Type\Php\SprintfFunctionDynamicReturnTypeExtension->getConstantType()
#6 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1774):
PHPStan\Type\Php\SprintfFunctionDynamicReturnTypeExtension->getTypeFromFunctionCall()
#7 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(622): PHPStan\Analyser\MutatingScope->resolveType()
#8 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(3656): PHPStan\Analyser\MutatingScope->getType()
#9 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2629): PHPStan\Analyser\NodeScopeResolver->processArgs()
#10 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2889): PHPStan\Analyser\NodeScopeResolver->processExprNode()
#11 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2825): PHPStan\Analyser\NodeScopeResolver->processExprNode()
#12 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(700): PHPStan\Analyser\NodeScopeResolver->processExprNode()
#13 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(465): PHPStan\Analyser\NodeScopeResolver->processStmtNode()
#14 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(653): PHPStan\Analyser\NodeScopeResolver->processStmtNodes()
#15 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(465): PHPStan\Analyser\NodeScopeResolver->processStmtNode()
#16 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(793): PHPStan\Analyser\NodeScopeResolver->processStmtNodes()
#17 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(465): PHPStan\Analyser\NodeScopeResolver->processStmtNode()
#18 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(760): PHPStan\Analyser\NodeScopeResolver->processStmtNodes()
#19 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(430): PHPStan\Analyser\NodeScopeResolver->processStmtNode()
#20 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(179): PHPStan\Analyser\NodeScopeResolver->processNodes()
#21 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(139): PHPStan\Analyser\FileAnalyser->analyseFile()
#22 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/EventEmitterTrait.php(111): PHPStan\Command\WorkerCommand::PHPStan\Command\{closure}()
#23 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(117): _PHPStan_2132cc0bd\Evenement\EventEmitter->emit()
#24 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/EventEmitterTrait.php(111): _PHPStan_2132cc0bd\Clue\React\NDJson\Decoder->handleData()
#25 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62): _PHPStan_2132cc0bd\Evenement\EventEmitter->emit()
#26 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/EventEmitterTrait.php(111):
_PHPStan_2132cc0bd\React\Stream\Util::_PHPStan_2132cc0bd\React\Stream\{closure}()
#27 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(168): _PHPStan_2132cc0bd\Evenement\EventEmitter->emit()
#28 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201):
_PHPStan_2132cc0bd\React\Stream\DuplexResourceStream->handleData()
#29 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173):
_PHPStan_2132cc0bd\React\EventLoop\StreamSelectLoop->waitForStreamActivity()
#30 phar:///vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(99): _PHPStan_2132cc0bd\React\EventLoop\StreamSelectLoop->run()
#31 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259): PHPStan\Command\WorkerCommand->execute()
#32 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(870): _PHPStan_2132cc0bd\Symfony\Component\Console\Command\Command->run()
#33 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(261): _PHPStan_2132cc0bd\Symfony\Component\Console\Application->doRunCommand()
#34 phar:///vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157): _PHPStan_2132cc0bd\Symfony\Component\Console\Application->doRun()
#35 phar:///vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(127): _PHPStan_2132cc0bd\Symfony\Component\Console\Application->run()
#36 phar:///vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(128): _PHPStan_2132cc0bd\{closure}()
#37 /vendor/phpstan/phpstan/phpstan(8): require('...')
#38 /vendor/bin/phpstan(120): include('...')
#39 {main}
Error: https://phpstan.org/r/9bb57ef8-e24d-498c-854a-7c0385faf32d
<?php declare(strict_types = 1);
enum FooBarEnum: string
{
case CASE_ONE = 'case_one';
case CASE_TWO = 'case_two';
case CASE_THREE = 'case_three';
case CASE_FOUR = 'case_four';
public function matchFunction(): string
{
return match ($this) {
self::CASE_ONE => 'one',
self::CASE_TWO => 'two',
default => throw new \Exception(
sprintf('"%s" is not implemented yet', get_debug_type($this))
)
};
}
}Same error: https://phpstan.org/r/7620c40a-efce-41ad-bedd-e27af0d1b5c7
<?php declare(strict_types = 1);
enum FooBarEnum: string
{
case CASE_ONE = 'case_one';
case CASE_TWO = 'case_two';
case CASE_THREE = 'case_three';
case CASE_FOUR = 'case_four';
public function matchFunction(): string
{
return match ($this) {
self::CASE_ONE => 'one',
self::CASE_TWO => 'two',
self::CASE_THREE, self::CASE_FOUR => throw new \Exception(
sprintf('"%s" is not implemented yet', get_debug_type($this))
)
};
}
}No error: https://phpstan.org/r/569233fd-482f-4b24-a5cc-f9641111d422
<?php declare(strict_types = 1);
enum FooBarEnum: string
{
case CASE_ONE = 'case_one';
case CASE_TWO = 'case_two';
case CASE_THREE = 'case_three';
case CASE_FOUR = 'case_four';
public function matchFunction(): string
{
return match ($this) {
self::CASE_ONE => 'one',
self::CASE_TWO => 'two',
self::CASE_THREE => 'three',
self::CASE_FOUR => throw new \Exception(
sprintf('"%s" is not implemented yet', get_debug_type($this))
)
};
}
}Also no error: https://phpstan.org/r/7d6e61b8-3429-469f-bab3-26c1dd506b8b
<?php declare(strict_types = 1);
enum FooBarEnum: string
{
case CASE_ONE = 'case_one';
case CASE_TWO = 'case_two';
case CASE_THREE = 'case_three';
case CASE_FOUR = 'case_four';
public function matchFunction(): string
{
return match ($this) {
self::CASE_ONE => 'one',
self::CASE_TWO => 'two',
self::CASE_THREE => 'three',
default => throw new \Exception(
sprintf('"%s" is not implemented yet', get_debug_type($this))
)
};
}
}This works also: https://phpstan.org/r/08663d62-9ae3-4f97-85f0-2dc7ddf23a8f
<?php declare(strict_types = 1);
enum FooBarEnum: string
{
case CASE_ONE = 'case_one';
case CASE_TWO = 'case_two';
case CASE_THREE = 'case_three';
case CASE_FOUR = 'case_four';
public function matchFunction(): string
{
return match ($this) {
self::CASE_ONE => 'one',
self::CASE_TWO => 'two',
self::CASE_THREE => throw new \Exception(
sprintf('"%s" is not implemented yet', get_debug_type($this))
),
default => throw new \Exception(
sprintf('"%s" is not implemented yet', get_debug_type($this))
)
};
}
}Code snippet that reproduces the problem
https://phpstan.org/r/9bb57ef8-e24d-498c-854a-7c0385faf32d
Expected output
Nothing
Did PHPStan help you today? Did it make you happy in any way?
PHPStan has often saved me from minor or major bugs. PHPStan is one of those tools that you get to know and never want to miss in a project again.
I was also very happy about the presentation at the last Symfony conference.