File tree 3 files changed +90
-1
lines changed
3 files changed +90
-1
lines changed Original file line number Diff line number Diff line change @@ -554,8 +554,28 @@ public function toArray(): Type
554
554
public function inferTemplateTypes (Type $ receivedType ): TemplateTypeMap
555
555
{
556
556
$ types = TemplateTypeMap::createEmpty ();
557
+ if ($ receivedType instanceof UnionType) {
558
+ $ myTypes = [];
559
+ $ remainingReceivedTypes = [];
560
+ foreach ($ receivedType ->getTypes () as $ receivedInnerType ) {
561
+ foreach ($ this ->types as $ type ) {
562
+ if ($ type ->isSuperTypeOf ($ receivedInnerType )->yes ()) {
563
+ $ types = $ types ->union ($ type ->inferTemplateTypes ($ receivedInnerType ));
564
+ continue 2 ;
565
+ }
566
+ $ myTypes [] = $ type ;
567
+ }
568
+ $ remainingReceivedTypes [] = $ receivedInnerType ;
569
+ }
570
+ if (count ($ remainingReceivedTypes ) === 0 ) {
571
+ return $ types ;
572
+ }
573
+ $ receivedType = TypeCombinator::union (...$ remainingReceivedTypes );
574
+ } else {
575
+ $ myTypes = $ this ->types ;
576
+ }
557
577
558
- foreach ($ this -> types as $ type ) {
578
+ foreach ($ myTypes as $ type ) {
559
579
$ types = $ types ->union ($ type ->inferTemplateTypes ($ receivedType ));
560
580
}
561
581
Original file line number Diff line number Diff line change @@ -5646,6 +5646,11 @@ public function dataBug4423(): array
5646
5646
return $ this ->gatherAssertTypes (__DIR__ . '/data/bug-4423.php ' );
5647
5647
}
5648
5648
5649
+ public function dataGenericUnions (): array
5650
+ {
5651
+ return $ this ->gatherAssertTypes (__DIR__ . '/data/generic-unions.php ' );
5652
+ }
5653
+
5649
5654
/**
5650
5655
* @dataProvider dataArrayFunctions
5651
5656
* @param string $description
@@ -11258,6 +11263,7 @@ private function gatherAssertTypes(string $file): array
11258
11263
* @dataProvider dataPseudoTypeOverrides
11259
11264
* @dataProvider dataGenericTraits
11260
11265
* @dataProvider dataBug4423
11266
+ * @dataProvider dataGenericUnions
11261
11267
* @param string $assertType
11262
11268
* @param string $file
11263
11269
* @param mixed ...$args
Original file line number Diff line number Diff line change
1
+ <?php
2
+
3
+ namespace GenericUnions ;
4
+
5
+ use function PHPStan \Analyser \assertType ;
6
+
7
+ class Foo
8
+ {
9
+
10
+ /**
11
+ * @template T
12
+ * @param T|null $p
13
+ * @return T
14
+ */
15
+ public function doFoo ($ p )
16
+ {
17
+ if ($ p === null ) {
18
+ throw new \Exception ();
19
+ }
20
+
21
+ return $ p ;
22
+ }
23
+
24
+ /**
25
+ * @template T
26
+ * @param T $p
27
+ * @return T
28
+ */
29
+ public function doBar ($ p )
30
+ {
31
+ return $ p ;
32
+ }
33
+
34
+ /**
35
+ * @template T
36
+ * @param T|int|float $p
37
+ * @return T
38
+ */
39
+ public function doBaz ($ p )
40
+ {
41
+ return $ p ;
42
+ }
43
+
44
+ /**
45
+ * @param int|string $stringOrInt
46
+ */
47
+ public function foo (
48
+ ?string $ nullableString ,
49
+ $ stringOrInt
50
+ ): void
51
+ {
52
+ assertType ('string ' , $ this ->doFoo ($ nullableString ));
53
+ assertType ('int|string ' , $ this ->doFoo ($ stringOrInt ));
54
+
55
+ assertType ('string|null ' , $ this ->doBar ($ nullableString ));
56
+
57
+ assertType ('int ' , $ this ->doBaz (1 ));
58
+ assertType ('string ' , $ this ->doBaz ('foo ' ));
59
+ assertType ('float ' , $ this ->doBaz (1.2 ));
60
+ assertType ('string ' , $ this ->doBaz ($ stringOrInt ));
61
+ }
62
+
63
+ }
You can’t perform that action at this time.
0 commit comments