Skip to content

Commit 3576292

Browse files
committed
RegexArrayShapeMatcher - Fix subject type for single optional capturing groups
1 parent 080280f commit 3576292

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

src/Type/Php/RegexArrayShapeMatcher.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
154154

155155
if (!$this->containsUnmatchedAsNull($flags ?? 0, $matchesAll)) {
156156
$combiType = TypeCombinator::union(
157-
new ConstantArrayType([new ConstantIntegerType(0)], [new StringType()], [0], [], true),
157+
new ConstantArrayType([new ConstantIntegerType(0)], [$this->createSubjectValueType($flags, $matchesAll)], [0], [], true),
158158
$combiType,
159159
);
160160
}
@@ -288,7 +288,7 @@ private function buildArrayType(
288288
// first item in matches contains the overall match.
289289
$builder->setOffsetValueType(
290290
$this->getKeyType(0),
291-
$this->createSubjectValueType($wasMatched, $flags, $matchesAll),
291+
$this->createSubjectValueType($flags, $matchesAll),
292292
$this->isSubjectOptional($wasMatched, $matchesAll),
293293
);
294294

@@ -351,7 +351,7 @@ private function isSubjectOptional(TrinaryLogic $wasMatched, bool $matchesAll):
351351
return !$wasMatched->yes();
352352
}
353353

354-
private function createSubjectValueType(TrinaryLogic $wasMatched, int $flags, bool $matchesAll): Type
354+
private function createSubjectValueType(int $flags, bool $matchesAll): Type
355355
{
356356
$subjectValueType = TypeCombinator::removeNull($this->getValueType(new StringType(), $flags, $matchesAll));
357357

tests/PHPStan/Analyser/nsrt/preg_match_shapes.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,3 +648,10 @@ function (string $s): void {
648648
assertType('array{string, non-empty-string}', $matches);
649649
}
650650
};
651+
652+
function (string $value): void
653+
{
654+
if (preg_match('/^(x)*$/', $value, $matches, PREG_OFFSET_CAPTURE)) {
655+
assertType("array{0: array{string, int<0, max>}, 1?: array{non-empty-string, int<0, max>}}", $matches);
656+
}
657+
};

0 commit comments

Comments
 (0)