File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -620,6 +620,20 @@ private static function reduceArrays(array $constantArrays): array
620620
621621 public static function intersect (Type ...$ types ): Type
622622 {
623+ usort ($ types , static function (Type $ a , Type $ b ): int {
624+ if (!$ a instanceof UnionType || !$ b instanceof UnionType) {
625+ return 0 ;
626+ }
627+
628+ if ($ a instanceof BenevolentUnionType) {
629+ return 1 ;
630+ }
631+ if ($ b instanceof BenevolentUnionType) {
632+ return -1 ;
633+ }
634+
635+ return 0 ;
636+ });
623637 // transform A & (B | C) to (A & B) | (A & C)
624638 foreach ($ types as $ i => $ type ) {
625639 if ($ type instanceof UnionType) {
@@ -632,7 +646,12 @@ public static function intersect(Type ...$types): Type
632646 );
633647 }
634648
635- return self ::union (...$ topLevelUnionSubTypes );
649+ $ union = self ::union (...$ topLevelUnionSubTypes );
650+ if ($ type instanceof BenevolentUnionType) {
651+ return TypeUtils::toBenevolentUnion ($ union );
652+ }
653+
654+ return $ union ;
636655 }
637656 }
638657
Original file line number Diff line number Diff line change @@ -9405,11 +9405,11 @@ public function dataPhp73Functions(): array
94059405 'array_key_last($mixedArray) ' ,
94069406 ],
94079407 [
9408- 'int|string ' ,
9408+ '( int|string) ' ,
94099409 'array_key_first($nonEmptyArray) ' ,
94109410 ],
94119411 [
9412- 'int|string ' ,
9412+ '( int|string) ' ,
94139413 'array_key_last($nonEmptyArray) ' ,
94149414 ],
94159415 [
@@ -10028,6 +10028,11 @@ public function dataClassPhpDocs(): array
1002810028 return $ this ->gatherAssertTypes (__DIR__ . '/data/classPhpDocs.php ' );
1002910029 }
1003010030
10031+ public function dataNonEmptyArrayKeyType (): array
10032+ {
10033+ return $ this ->gatherAssertTypes (__DIR__ . '/data/non-empty-array-key-type.php ' );
10034+ }
10035+
1003110036 /**
1003210037 * @dataProvider dataBug2574
1003310038 * @dataProvider dataBug2577
@@ -10092,6 +10097,7 @@ public function dataClassPhpDocs(): array
1009210097 * @dataProvider dataMinMaxReturnTypeWithArrays
1009310098 * @dataProvider dataNativeStaticReturnType
1009410099 * @dataProvider dataClassPhpDocs
10100+ * @dataProvider dataNonEmptyArrayKeyType
1009510101 * @param string $assertType
1009610102 * @param string $file
1009710103 * @param mixed ...$args
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace NonEmptyArrayKeyType ;
4+
5+ use function PHPStan \Analyser \assertType ;
6+
7+ class Foo
8+ {
9+
10+ /**
11+ * @param \stdClass[] $items
12+ */
13+ public function doFoo (array $ items )
14+ {
15+ assertType ('array<stdClass> ' , $ items );
16+
17+ if (count ($ items ) > 0 ) {
18+ assertType ('array<stdClass>&nonEmpty ' , $ items );
19+ foreach ($ items as $ i => $ val ) {
20+ assertType ('(int|string) ' , $ i );
21+ assertType ('stdClass ' , $ val );
22+ }
23+ }
24+ }
25+
26+ /**
27+ * @param \stdClass[] $items
28+ */
29+ public function doBar (array $ items )
30+ {
31+ foreach ($ items as $ i => $ val ) {
32+ assertType ('(int|string) ' , $ i );
33+ assertType ('stdClass ' , $ val );
34+ }
35+ }
36+
37+ }
Original file line number Diff line number Diff line change @@ -2782,6 +2782,14 @@ public function dataIntersect(): array
27822782 IntersectionType::class,
27832783 'string&hasOffset(int) ' ,
27842784 ],
2785+ [
2786+ [
2787+ new BenevolentUnionType ([new IntegerType (), new StringType ()]),
2788+ new MixedType (),
2789+ ],
2790+ BenevolentUnionType::class,
2791+ '(int|string) ' ,
2792+ ],
27852793 ];
27862794 }
27872795
You can’t perform that action at this time.
0 commit comments