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 src/Type/Constant/ConstantArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ public function getAllArrays(): array
}

$builder = ConstantArrayTypeBuilder::createEmpty();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have similar code in the codebase which asserts the result of a getArray-method call on a ConstantArrayTypeBuilder object ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both tests and static analysis pass.

The reviewer's question was informational — asking whether there are similar patterns elsewhere in the codebase. The answer is no: the getAllArrays() assertion at ConstantArrayType.php:250 is the only place that asserts getArray() returns a ConstantArrayType. No code changes are needed beyond what's already in the PR. There's nothing to commit or push.

$builder->disableArrayDegradation();
foreach ($keys as $i) {
$builder->setOffsetValueType($this->keyTypes[$i], $this->valueTypes[$i]);
}
Expand Down
7 changes: 7 additions & 0 deletions tests/PHPStan/Analyser/AnalyserIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,13 @@ public function testBigPhpdocArrayShape(): void
$this->assertNoErrors($errors);
}

public function testBug14324(): void
{
// crash
$errors = $this->runAnalyse(__DIR__ . '/data/bug-14324.php');
$this->assertNoErrors($errors);
}

/**
* @param string[]|null $allAnalysedFiles
* @return list<Error>
Expand Down
63 changes: 63 additions & 0 deletions tests/PHPStan/Analyser/data/bug-14324.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php declare(strict_types = 1);

namespace Bug14324;
Comment thread
staabm marked this conversation as resolved.

use function PHPStan\Testing\assertType;

final class Test
{
private const ADDITIONAL_MAPS = [
'foo-',
'bar-',
'baz-',
];

/** @var array<string, callable(): string> */
private static array $map = [];

public function createMap(): void
{
if ([] === self::$map) {
// 29 entries
self::$map = [
'foo' => static fn() => 'foo',
'bar' => static fn() => 'bar',
'baz' => static fn() => 'baz',
'qux' => static fn() => 'qux',
'quux' => static fn() => 'quux',
'corge' => static fn() => 'corge',
'grault' => static fn() => 'grault',
'garply' => static fn() => 'garply',
'waldo' => static fn() => 'waldo',
'fred' => static fn() => 'fred',
'plugh' => static fn() => 'plugh',
'xyzzy' => static fn() => 'xyzzy',
'thud' => static fn() => 'thud',
'foo1' => static fn() => 'foo1',
'bar1' => static fn() => 'bar1',
'baz1' => static fn() => 'baz1',
'qux1' => static fn() => 'qux1',
'quux1' => static fn() => 'quux1',
'corge1' => static fn() => 'corge1',
'grault1' => static fn() => 'grault1',
'garply1' => static fn() => 'garply1',
'waldo1' => static fn() => 'waldo1',
'fred1' => static fn() => 'fred1',
'plugh1' => static fn() => 'plugh1',
'xyzzy1' => static fn() => 'xyzzy1',
'thud1' => static fn() => 'thud1',
'foo2' => static fn() => 'foo2',
'bar2' => static fn() => 'bar2',
'baz2' => static fn() => 'baz2',
];
assertType("array{foo: Closure(): 'foo', bar: Closure(): 'bar', baz: Closure(): 'baz', qux: Closure(): 'qux', quux: Closure(): 'quux', corge: Closure(): 'corge', grault: Closure(): 'grault', garply: Closure(): 'garply', waldo: Closure(): 'waldo', fred: Closure(): 'fred', plugh: Closure(): 'plugh', xyzzy: Closure(): 'xyzzy', thud: Closure(): 'thud', foo1: Closure(): 'foo1', bar1: Closure(): 'bar1', baz1: Closure(): 'baz1', qux1: Closure(): 'qux1', quux1: Closure(): 'quux1', corge1: Closure(): 'corge1', grault1: Closure(): 'grault1', garply1: Closure(): 'garply1', waldo1: Closure(): 'waldo1', fred1: Closure(): 'fred1', plugh1: Closure(): 'plugh1', xyzzy1: Closure(): 'xyzzy1', thud1: Closure(): 'thud1', foo2: Closure(): 'foo2', bar2: Closure(): 'bar2', baz2: Closure(): 'baz2'}", self::$map);

foreach (self::ADDITIONAL_MAPS as $map) {
// added with 3 entries, breaching the closure limit of 32 entries
self::$map[$map] = fn () => self::$map['foo']();
}

assertType("non-empty-array<'bar'|'bar-'|'bar1'|'bar2'|'baz'|'baz-'|'baz1'|'baz2'|'corge'|'corge1'|'foo'|'foo-'|'foo1'|'foo2'|'fred'|'fred1'|'garply'|'garply1'|'grault'|'grault1'|'plugh'|'plugh1'|'quux'|'quux1'|'qux'|'qux1'|'thud'|'thud1'|'waldo'|'waldo1'|'xyzzy'|'xyzzy1', callable(): mixed>&oversized-array", self::$map);
}
}
}
Loading