Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ parameters:
- RecursiveCallbackFilterIterator
- AppendIterator
- NoRewindIterator
- LimitIterator
explicitMixedInUnknownGenericNew: false
explicitMixedForGlobalVariables: false
explicitMixedViaIsArray: false
Expand Down
24 changes: 24 additions & 0 deletions stubs/iterable.stub
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,27 @@ class NoRewindIterator extends IteratorIterator {
public function key() {}
}

/**
* @template-covariant TKey
* @template-covariant TValue
* @template TIterator as Iterator<TKey, TValue>
*
* @template-implements OuterIterator<TKey, TValue>
* @template-extends IteratorIterator<TKey, TValue, TIterator>
*/
class LimitIterator extends IteratorIterator implements OuterIterator {
/**
* @param TIterator $iterator
*/
public function __construct(Iterator $iterator, int $offset = 0, int $count = -1) {}

/**
* @return TValue
*/
public function current() {}

/**
* @return TKey
*/
public function key() {}
}
10 changes: 6 additions & 4 deletions tests/PHPStan/Analyser/AnalyserIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -602,13 +602,15 @@ public function testBug6896(): void
}

$errors = $this->runAnalyse(__DIR__ . '/data/bug-6896.php');
$this->assertCount(3, $errors);
$this->assertCount(4, $errors);
$this->assertSame('Generic type IteratorIterator<(int|string), mixed> in PHPDoc tag @return does not specify all template types of class IteratorIterator: TKey, TValue, TIterator', $errors[0]->getMessage());
$this->assertSame(38, $errors[0]->getLine());
$this->assertSame('Method Bug6896\RandHelper::getPseudoRandomWithUrl() return type with generic class Bug6896\XIterator does not specify its types: TKey, TValue', $errors[1]->getMessage());
$this->assertSame('Generic type LimitIterator<(int|string), mixed> in PHPDoc tag @return does not specify all template types of class LimitIterator: TKey, TValue, TIterator', $errors[1]->getMessage());
$this->assertSame(38, $errors[1]->getLine());
$this->assertSame('Method Bug6896\RandHelper::getPseudoRandomWithUrl() should return array<TRandKey of (int|string), TRandVal>|Bug6896\XIterator<TRandKey of (int|string), TRandVal>|(iterable<TRandKey of (int|string), TRandVal>&LimitIterator)|IteratorIterator<TRandKey of (int|string), TRandVal> but returns TRandList of array<TRandKey of (int|string), TRandVal>|Traversable<TRandKey of (int|string), TRandVal>.', $errors[2]->getMessage());
$this->assertSame(42, $errors[2]->getLine());
$this->assertSame('Method Bug6896\RandHelper::getPseudoRandomWithUrl() return type with generic class Bug6896\XIterator does not specify its types: TKey, TValue', $errors[2]->getMessage());
$this->assertSame(38, $errors[2]->getLine());
$this->assertSame('Method Bug6896\RandHelper::getPseudoRandomWithUrl() should return array<TRandKey of (int|string), TRandVal>|Bug6896\XIterator<TRandKey of (int|string), TRandVal>|IteratorIterator<TRandKey of (int|string), TRandVal>|LimitIterator<TRandKey of (int|string), TRandVal> but returns TRandList of array<TRandKey of (int|string), TRandVal>|Traversable<TRandKey of (int|string), TRandVal>.', $errors[3]->getMessage());
$this->assertSame(42, $errors[3]->getLine());
}

public function testBug6940(): void
Expand Down