diff --git a/src/Rules/Variables/NullCoalesceRule.php b/src/Rules/Variables/NullCoalesceRule.php index 7a1184de91..28b8a522a1 100644 --- a/src/Rules/Variables/NullCoalesceRule.php +++ b/src/Rules/Variables/NullCoalesceRule.php @@ -8,6 +8,7 @@ use PHPStan\Rules\Rule; use PHPStan\Type\NullType; use PHPStan\Type\Type; +use PHPStan\Type\VoidType; /** * @implements Rule @@ -27,12 +28,13 @@ public function getNodeType(): string public function processNode(Node $node, Scope $scope): array { $typeMessageCallback = static function (Type $type): ?string { + $isVoid = (new VoidType())->isSuperTypeOf($type); $isNull = (new NullType())->isSuperTypeOf($type); - if ($isNull->maybe()) { + if ($isNull->maybe() || $isVoid->maybe()) { return null; } - if ($isNull->yes()) { + if ($isNull->yes() || $isVoid->yes()) { return 'is always null'; } diff --git a/tests/PHPStan/Rules/Variables/NullCoalesceRuleTest.php b/tests/PHPStan/Rules/Variables/NullCoalesceRuleTest.php index 613770aead..53c1a3a53e 100644 --- a/tests/PHPStan/Rules/Variables/NullCoalesceRuleTest.php +++ b/tests/PHPStan/Rules/Variables/NullCoalesceRuleTest.php @@ -368,4 +368,17 @@ public function testBug8084(): void $this->analyse([__DIR__ . '/data/bug-8084.php'], []); } + public function testVoid(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->strictUnnecessaryNullsafePropertyFetch = true; + + $this->analyse([__DIR__ . '/data/null-coalesce-void.php'], [ + [ + 'Expression on left side of ?? is always null.', + 22, + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Variables/data/null-coalesce-void.php b/tests/PHPStan/Rules/Variables/data/null-coalesce-void.php new file mode 100644 index 0000000000..c90448cf9c --- /dev/null +++ b/tests/PHPStan/Rules/Variables/data/null-coalesce-void.php @@ -0,0 +1,22 @@ += 8.0 + +namespace CoalesceRuleVoid; + +/** @return array|void */ +function get_post_custom_keys($maybe = false) +{ + if ($maybe) { + return; + } + + return []; +} + +function foo_bar(): void +{ + return; +} + +$test1 = get_post_custom_keys(true) ?? 'foo'; + +$test2 = foo_bar() ?? 'bar';