Skip to content

Commit 7125e1b

Browse files
authored
Fix preg_match_all with PREG_SET_ORDER does not see capture group as optional
1 parent 133c60e commit 7125e1b

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

Diff for: src/Type/Php/RegexArrayShapeMatcher.php

+14-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,20 @@ private function isGroupOptional(RegexCapturingGroup $captureGroup, TrinaryLogic
417417
private function createGroupValueType(RegexCapturingGroup $captureGroup, TrinaryLogic $wasMatched, int $flags, bool $isTrailingOptional, bool $isLastGroup, bool $matchesAll): Type
418418
{
419419
if ($matchesAll) {
420-
if (!$this->containsSetOrder($flags) && !$this->containsUnmatchedAsNull($flags, $matchesAll) && $captureGroup->isOptional()) {
420+
if (
421+
(
422+
!$this->containsSetOrder($flags)
423+
&& !$this->containsUnmatchedAsNull($flags, $matchesAll)
424+
&& $captureGroup->isOptional()
425+
)
426+
||
427+
(
428+
$this->containsSetOrder($flags)
429+
&& !$this->containsUnmatchedAsNull($flags, $matchesAll)
430+
&& $captureGroup->isOptional()
431+
&& !$isTrailingOptional
432+
)
433+
) {
421434
$groupValueType = $this->getValueType(
422435
TypeCombinator::union($captureGroup->getType(), new ConstantStringType('')),
423436
$flags,

Diff for: tests/PHPStan/Analyser/nsrt/preg_match_all_shapes.php

+9
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,12 @@ function doFoobarNull(string $s): void {
175175
}
176176
}
177177
}
178+
179+
function bug11661(): void {
180+
preg_match_all('/(ERR)?(.+)/', 'abc', $results, PREG_SET_ORDER);
181+
assertType("list<array{string, ''|'ERR', non-empty-string}>", $results);
182+
183+
preg_match_all('/(ERR)?.+/', 'abc', $results, PREG_SET_ORDER);
184+
assertType("list<array{0: string, 1?: 'ERR'}>", $results);
185+
186+
}

0 commit comments

Comments
 (0)