Skip to content

Commit b116e71

Browse files
staabmondrejmirtes
authored andcommitted
RegexArrayShapeMatcher - Fix PREG_UNMATCHED_AS_NULL with top level alternation
1 parent 7d3be58 commit b116e71

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

src/Type/Php/RegexArrayShapeMatcher.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
170170
$beforeCurrentCombo = false;
171171
} elseif ($beforeCurrentCombo && !$group->resetsGroupCounter()) {
172172
$group->forceNonOptional();
173-
} elseif ($group->getAlternationId() === $onlyTopLevelAlternationId) {
173+
} elseif ($group->getAlternationId() === $onlyTopLevelAlternationId && !$this->containsUnmatchedAsNull($flags ?? 0)) {
174174
unset($comboList[$groupId]);
175175
}
176176
}
@@ -191,7 +191,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
191191
}
192192
}
193193

194-
if ($isOptionalAlternation) {
194+
if ($isOptionalAlternation && !$this->containsUnmatchedAsNull($flags ?? 0)) {
195195
$combiTypes[] = new ConstantArrayType([new ConstantIntegerType(0)], [new StringType()], [0], [], true);
196196
}
197197

tests/PHPStan/Analyser/nsrt/bug-11311.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,17 @@ function bug11331c(string $url):void {
6565
assertType('array{string, string|null, string|null, string, string}', $matches);
6666
}
6767
}
68+
69+
class UnmatchedAsNullWithTopLevelAlternation {
70+
function doFoo(string $s): void {
71+
if (preg_match('/Price: (?:(£)|(€))\d+/', $s, $matches, PREG_UNMATCHED_AS_NULL)) {
72+
assertType('array{string, string|null, string|null}', $matches); // could be array{0: string, 1: null, 2: string}|array{0: string, 1: string, 2: null}
73+
}
74+
}
75+
76+
function doBar(string $s): void {
77+
if (preg_match('/Price: (?:(£)|(€))?\d+/', $s, $matches, PREG_UNMATCHED_AS_NULL)) {
78+
assertType('array{string, string|null, string|null}', $matches);
79+
}
80+
}
81+
}

0 commit comments

Comments
 (0)