Skip to content

Commit 4a0950f

Browse files
VincentLangletphpstan-bot
authored andcommitted
Fix RegexIterator returning generic type with unresolved template parameters
- Fixed GenericTypeTemplateTraverser to continue traversing into bounds of unresolvable template types - When a template type (like TIterator) can't be inferred from constructor args, its bound may still contain other template types (TKey, TValue) that need resolution - Added regression test for phpstan/phpstan#13325
1 parent 7b8a821 commit 4a0950f

3 files changed

Lines changed: 24 additions & 1 deletion

File tree

src/Analyser/Traverser/GenericTypeTemplateTraverser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function traverse(Type $type, callable $traverse): Type
2626
if ($type instanceof TemplateType && !$type->isArgument()) {
2727
$newType = $this->resolvedTemplateTypeMap->getType($type->getName());
2828
if ($newType === null || $newType instanceof ErrorType) {
29-
return $type->getDefault() ?? $type->getBound();
29+
return $traverse($type->getDefault() ?? $type->getBound());
3030
}
3131

3232
return TemplateTypeHelper::generalizeInferredTemplateType($type, $newType);

tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,4 +1326,9 @@ public function testBug10924(): void
13261326
$this->analyse([__DIR__ . '/data/bug-10924.php'], []);
13271327
}
13281328

1329+
public function testBug13325(): void
1330+
{
1331+
$this->analyse([__DIR__ . '/data/bug-13325.php'], []);
1332+
}
1333+
13291334
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Bug13325;
6+
7+
use Iterator;
8+
use RegexIterator;
9+
use Traversable;
10+
11+
final class Foo
12+
{
13+
/** @return RegexIterator<mixed, mixed, Traversable<mixed, mixed>> */
14+
public function __invoke(Iterator $iterator): RegexIterator
15+
{
16+
return new RegexIterator($iterator, 'string');
17+
}
18+
}

0 commit comments

Comments
 (0)