1--TEST--
2Union types in reflection
3--INI--
4error_reporting=E_ALL&~E_DEPRECATED
5--FILE--
6<?php
7
8function dumpType(ReflectionUnionType $rt) {
9    echo "Type $rt:\n";
10    echo "Allows null: " . ($rt->allowsNull() ? "true" : "false") . "\n";
11    foreach ($rt->getTypes() as $type) {
12        echo "  Name: " . $type->getName() . "\n";
13        echo "  String: " . (string) $type . "\n";
14        echo "  Allows Null: " . ($type->allowsNull() ? "true" : "false") . "\n";
15    }
16}
17
18function test1(): X|Y|int|float|false|null { }
19function test2(): X|iterable|bool { }
20
21class Test {
22    public X|Y|int $prop;
23}
24
25dumpType((new ReflectionFunction('test1'))->getReturnType());
26dumpType((new ReflectionFunction('test2'))->getReturnType());
27
28$rc = new ReflectionClass(Test::class);
29$rp = $rc->getProperty('prop');
30dumpType($rp->getType());
31
32/* Force CE resolution of the property type */
33
34class x {}
35$test = new Test;
36$test->prop = new x;
37
38$rp = $rc->getProperty('prop');
39dumpType($rp->getType());
40
41class y {}
42$test->prop = new y;
43
44$rp = $rc->getProperty('prop');
45dumpType($rp->getType());
46
47?>
48--EXPECT--
49Type X|Y|int|float|false|null:
50Allows null: true
51  Name: X
52  String: X
53  Allows Null: false
54  Name: Y
55  String: Y
56  Allows Null: false
57  Name: int
58  String: int
59  Allows Null: false
60  Name: float
61  String: float
62  Allows Null: false
63  Name: false
64  String: false
65  Allows Null: false
66  Name: null
67  String: null
68  Allows Null: true
69Type X|iterable|bool:
70Allows null: false
71  Name: X
72  String: X
73  Allows Null: false
74  Name: iterable
75  String: iterable
76  Allows Null: false
77  Name: bool
78  String: bool
79  Allows Null: false
80Type X|Y|int:
81Allows null: false
82  Name: X
83  String: X
84  Allows Null: false
85  Name: Y
86  String: Y
87  Allows Null: false
88  Name: int
89  String: int
90  Allows Null: false
91Type x|Y|int:
92Allows null: false
93  Name: x
94  String: x
95  Allows Null: false
96  Name: Y
97  String: Y
98  Allows Null: false
99  Name: int
100  String: int
101  Allows Null: false
102Type x|y|int:
103Allows null: false
104  Name: x
105  String: x
106  Allows Null: false
107  Name: y
108  String: y
109  Allows Null: false
110  Name: int
111  String: int
112  Allows Null: false
113