File tree 2 files changed +54
-3
lines changed
ext/reflection/tests/types
2 files changed +54
-3
lines changed Original file line number Diff line number Diff line change @@ -6527,10 +6527,24 @@ static zend_type zend_compile_typename(
6527
6527
6528
6528
ZEND_ASSERT (list -> children == type_list -> num_types );
6529
6529
6530
- ZEND_TYPE_SET_LIST (type , type_list );
6531
6530
ZEND_TYPE_FULL_MASK (type ) |= _ZEND_TYPE_ARENA_BIT ;
6532
- /* Inform that the type list is an intersection type */
6533
- ZEND_TYPE_FULL_MASK (type ) |= _ZEND_TYPE_INTERSECTION_BIT ;
6531
+ /* An implicitly nullable intersection type needs to be converted to a DNF type */
6532
+ if (force_allow_null ) {
6533
+ zend_type intersection_type = ZEND_TYPE_INIT_NONE (0 );
6534
+ ZEND_TYPE_SET_LIST (intersection_type , type_list );
6535
+ ZEND_TYPE_FULL_MASK (intersection_type ) |= _ZEND_TYPE_INTERSECTION_BIT ;
6536
+
6537
+ zend_type_list * dnf_type_list = zend_arena_alloc (& CG (arena ), ZEND_TYPE_LIST_SIZE (list -> children ));
6538
+ dnf_type_list -> num_types = 1 ;
6539
+ dnf_type_list -> types [0 ] = intersection_type ;
6540
+ ZEND_TYPE_SET_LIST (type , dnf_type_list );
6541
+ /* Inform that the type list is a DNF type */
6542
+ ZEND_TYPE_FULL_MASK (type ) |= _ZEND_TYPE_UNION_BIT ;
6543
+ } else {
6544
+ ZEND_TYPE_SET_LIST (type , type_list );
6545
+ /* Inform that the type list is an intersection type */
6546
+ ZEND_TYPE_FULL_MASK (type ) |= _ZEND_TYPE_INTERSECTION_BIT ;
6547
+ }
6534
6548
} else {
6535
6549
type = zend_compile_single_typename (ast );
6536
6550
}
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ Intersection type which is implicitly nullable should be a DNF type in reflection
3
+ --FILE--
4
+ <?php
5
+
6
+ function dumpType (ReflectionType $ rt , int $ indent = 0 ) {
7
+ $ str_indent = str_repeat (' ' , 2 * $ indent );
8
+ echo $ str_indent . "Type $ rt is " . $ rt ::class . ": \n" ;
9
+ echo $ str_indent . "Allows Null: " . json_encode ($ rt ->allowsNull ()) . "\n" ;
10
+ foreach ($ rt ->getTypes () as $ type ) {
11
+ if ($ type instanceof ReflectionNamedType) {
12
+ echo $ str_indent . " Name: " . $ type ->getName () . "\n" ;
13
+ echo $ str_indent . " String: " . (string ) $ type . "\n" ;
14
+ } else {
15
+ dumpType ($ type , $ indent +1 );
16
+ }
17
+ }
18
+ }
19
+
20
+ function foo (X &Y $ foo = null ) {
21
+ var_dump ($ foo );
22
+ }
23
+
24
+ dumpType ((new ReflectionFunction ('foo ' ))->getParameters ()[0 ]->getType ());
25
+
26
+ ?>
27
+ --EXPECT--
28
+ Type (X&Y)|null is ReflectionUnionType:
29
+ Allows Null: true
30
+ Type X&Y is ReflectionIntersectionType:
31
+ Allows Null: false
32
+ Name: X
33
+ String: X
34
+ Name: Y
35
+ String: Y
36
+ Name: null
37
+ String: null
You can’t perform that action at this time.
0 commit comments