Skip to content

Commit 746de74

Browse files
committed
Fixed collapsing of constant arrays
1 parent 6348cc3 commit 746de74

File tree

5 files changed

+132
-2
lines changed

5 files changed

+132
-2
lines changed

phpstan-baseline.neon

+1-1
Original file line numberDiff line numberDiff line change
@@ -1549,7 +1549,7 @@ parameters:
15491549

15501550
-
15511551
message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantArrayType is error\\-prone and deprecated\\. Use Type\\:\\:getConstantArrays\\(\\) instead\\.$#"
1552-
count: 12
1552+
count: 10
15531553
path: src/Type/TypeCombinator.php
15541554

15551555
-

src/Type/TypeCombinator.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ private static function compareTypesInUnion(Type $a, Type $b): ?array
354354
return [new HasOffsetValueType($a->getOffsetType(), self::union($a->getValueType(), $b->getValueType())), null];
355355
}
356356
}
357-
if ($a instanceof ConstantArrayType && $b instanceof ConstantArrayType) {
357+
if ($a->isConstantArray()->yes() && $b->isConstantArray()->yes()) {
358358
return null;
359359
}
360360

tests/PHPStan/Analyser/NodeScopeResolverTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ public function dataFileAsserts(): iterable
226226
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-3915.php');
227227

228228
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-2378.php');
229+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9985.php');
229230
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6294.php');
230231
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-2580.php');
231232
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9753.php');
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Bug9985;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
function (): void {
8+
$warnings = [];
9+
10+
if (rand(0, 100) >= 1) {
11+
$warnings['a'] = true;
12+
}
13+
14+
if (rand(0, 100) >= 2) {
15+
$warnings['b'] = true;
16+
} elseif (rand(0, 100) >= 3) {
17+
$warnings['c'] = true;
18+
}
19+
20+
assertType('array{}|array{a?: true, b: true}|array{a?: true, c?: true}', $warnings);
21+
22+
if (!empty($warnings)) {
23+
assertType('array{a?: true, b: true}|(array{a?: true, c?: true}&non-empty-array)', $warnings);
24+
}
25+
};

tests/PHPStan/Type/TypeCombinatorTest.php

+104
Original file line numberDiff line numberDiff line change
@@ -2450,6 +2450,50 @@ public function dataUnion(): iterable
24502450
NeverType::class,
24512451
'*NEVER*',
24522452
];
2453+
yield [
2454+
[
2455+
new ConstantArrayType([
2456+
new ConstantStringType('a'),
2457+
new ConstantStringType('b'),
2458+
], [
2459+
new ConstantBooleanType(true),
2460+
new ConstantBooleanType(true),
2461+
], [0], [0]),
2462+
new ConstantArrayType([
2463+
new ConstantStringType('a'),
2464+
new ConstantStringType('c'),
2465+
], [
2466+
new ConstantBooleanType(true),
2467+
new ConstantBooleanType(true),
2468+
], [0], [0, 1]),
2469+
],
2470+
UnionType::class,
2471+
'array{a?: true, b: true}|array{a?: true, c?: true}',
2472+
];
2473+
2474+
yield [
2475+
[
2476+
new ConstantArrayType([
2477+
new ConstantStringType('a'),
2478+
new ConstantStringType('b'),
2479+
], [
2480+
new ConstantBooleanType(true),
2481+
new ConstantBooleanType(true),
2482+
], [0], [0]),
2483+
new IntersectionType([
2484+
new ConstantArrayType([
2485+
new ConstantStringType('a'),
2486+
new ConstantStringType('c'),
2487+
], [
2488+
new ConstantBooleanType(true),
2489+
new ConstantBooleanType(true),
2490+
], [0], [0, 1]),
2491+
new NonEmptyArrayType(),
2492+
]),
2493+
],
2494+
UnionType::class,
2495+
'array{a?: true, b: true}|(array{a?: true, c?: true}&non-empty-array)',
2496+
];
24532497
}
24542498

24552499
/**
@@ -4030,6 +4074,66 @@ public function dataIntersect(): iterable
40304074
NonAcceptingNeverType::class,
40314075
'never=explicit',
40324076
];
4077+
yield [
4078+
[
4079+
new UnionType([
4080+
new ConstantArrayType([], []),
4081+
new ConstantArrayType([
4082+
new ConstantStringType('a'),
4083+
new ConstantStringType('b'),
4084+
], [
4085+
new ConstantBooleanType(true),
4086+
new ConstantBooleanType(true),
4087+
], [0], [0]),
4088+
new ConstantArrayType([
4089+
new ConstantStringType('a'),
4090+
new ConstantStringType('c'),
4091+
], [
4092+
new ConstantBooleanType(true),
4093+
new ConstantBooleanType(true),
4094+
], [0], [0, 1]),
4095+
]),
4096+
new NonEmptyArrayType(),
4097+
],
4098+
UnionType::class,
4099+
'array{a?: true, b: true}|(array{a?: true, c?: true}&non-empty-array)',
4100+
];
4101+
yield [
4102+
[
4103+
new ConstantArrayType([], []),
4104+
new NonEmptyArrayType(),
4105+
],
4106+
NeverType::class,
4107+
'*NEVER*=implicit',
4108+
];
4109+
yield [
4110+
[
4111+
new ConstantArrayType([
4112+
new ConstantStringType('a'),
4113+
new ConstantStringType('b'),
4114+
], [
4115+
new ConstantBooleanType(true),
4116+
new ConstantBooleanType(true),
4117+
], [0], [0]),
4118+
new NonEmptyArrayType(),
4119+
],
4120+
ConstantArrayType::class,
4121+
'array{a?: true, b: true}',
4122+
];
4123+
yield [
4124+
[
4125+
new ConstantArrayType([
4126+
new ConstantStringType('a'),
4127+
new ConstantStringType('c'),
4128+
], [
4129+
new ConstantBooleanType(true),
4130+
new ConstantBooleanType(true),
4131+
], [0], [0, 1]),
4132+
new NonEmptyArrayType(),
4133+
],
4134+
IntersectionType::class,
4135+
'array{a?: true, c?: true}&non-empty-array',
4136+
];
40334137
}
40344138

40354139
/**

0 commit comments

Comments
 (0)