1--TEST-- 2Intersection type which is implicitly nullable should be a DNF type in reflection 3--FILE-- 4<?php 5 6function 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 20function foo(X&Y $foo = null) { 21 var_dump($foo); 22} 23 24dumpType((new ReflectionFunction('foo'))->getParameters()[0]->getType()); 25 26?> 27--EXPECTF-- 28Deprecated: foo(): Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in %s on line %d 29Type (X&Y)|null is ReflectionUnionType: 30Allows Null: true 31 Type X&Y is ReflectionIntersectionType: 32 Allows Null: false 33 Name: X 34 String: X 35 Name: Y 36 String: Y 37 Name: null 38 String: null 39