Skip to content

Commit 07f7a1b

Browse files
github-actions[bot]phpstan-bot
authored andcommitted
Fix false match.unhandled on array with multiple booleans
- Fixed TypeCombinator::remove() to handle removal of types with multiple finite types - Previously only removed types with exactly 1 finite type, now handles any count - This caused match expressions with array conditions and multi-condition arms to not narrow types properly - New regression test in tests/PHPStan/Rules/Comparison/data/bug-13029.php Closes phpstan/phpstan#13029
1 parent 1bbe9dc commit 07f7a1b

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

src/Type/TypeCombinator.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,13 @@ public static function remove(Type $fromType, Type $typeToRemove): Type
9090
$fromFiniteTypes = $fromType->getFiniteTypes();
9191
if (count($fromFiniteTypes) > 0) {
9292
$finiteTypesToRemove = $typeToRemove->getFiniteTypes();
93-
if (count($finiteTypesToRemove) === 1) {
93+
if (count($finiteTypesToRemove) > 0) {
9494
$result = [];
9595
foreach ($fromFiniteTypes as $finiteType) {
96-
if ($finiteType->equals($finiteTypesToRemove[0])) {
97-
continue;
96+
foreach ($finiteTypesToRemove as $finiteTypeToRemove) {
97+
if ($finiteType->equals($finiteTypeToRemove)) {
98+
continue 2;
99+
}
98100
}
99101

100102
$result[] = $finiteType;

tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@ public function testBug9534(): void
446446
]);
447447
}
448448

449+
#[RequiresPhp('>= 8.0')]
450+
public function testBug13029(): void
451+
{
452+
$this->analyse([__DIR__ . '/data/bug-13029.php'], []);
453+
}
454+
449455
#[RequiresPhp('>= 8.0')]
450456
public function testBug11310(): void
451457
{
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php // lint >= 8.0
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug13029;
6+
7+
function foo(): void
8+
{
9+
/** @var bool **/
10+
$bool1 = true;
11+
/** @var bool **/
12+
$bool2 = false;
13+
14+
$x = match([$bool1, $bool2]) {
15+
[true, false], [true, true] => 1,
16+
[false, false] => 0,
17+
[false, true] => -1,
18+
};
19+
}

0 commit comments

Comments
 (0)