1--TEST-- 2Test "or null"/"or be null" in type-checking errors for userland functions 3--FILE-- 4<?php 5 6// This should test every branch in zend_execute.c's `zend_verify_arg_type`, `zend_verify_return_type` and `zend_verify_missing_return_type` functions which produces an "or null"/"or be null" part in its error message 7 8function unloadedClass(?I\Dont\Exist $param) {} 9 10try { 11 unloadedClass(new \StdClass); 12} catch (\TypeError $e) { 13 echo $e, PHP_EOL; 14} 15 16class RealClass {} 17interface RealInterface {} 18 19function loadedClass(?RealClass $param) {} 20function loadedInterface(?RealInterface $param) {} 21 22try { 23 loadedClass(new \StdClass); 24} catch (\TypeError $e) { 25 echo $e, PHP_EOL; 26} 27 28try { 29 loadedInterface(new \StdClass); 30} catch (\TypeError $e) { 31 echo $e, PHP_EOL; 32} 33 34try { 35 unloadedClass(1); 36} catch (\TypeError $e) { 37 echo $e, PHP_EOL; 38} 39 40try { 41 loadedClass(1); 42} catch (\TypeError $e) { 43 echo $e, PHP_EOL; 44} 45 46try { 47 loadedInterface(1); 48} catch (\TypeError $e) { 49 echo $e, PHP_EOL; 50} 51 52function callableF(?callable $param) {} 53 54try { 55 callableF(1); 56} catch (\TypeError $e) { 57 echo $e, PHP_EOL; 58} 59 60function iterableF(?iterable $param) {} 61 62try { 63 iterableF(1); 64} catch (\TypeError $e) { 65 echo $e, PHP_EOL; 66} 67 68function intF(?int $param) {} 69 70try { 71 intF(new StdClass); 72} catch (\TypeError $e) { 73 echo $e, PHP_EOL; 74} 75 76function returnUnloadedClass(): ?I\Dont\Exist { 77 return new \StdClass; 78} 79 80try { 81 returnUnloadedClass(); 82} catch (\TypeError $e) { 83 echo $e, PHP_EOL; 84} 85 86function returnLoadedClass(): ?RealClass { 87 return new \StdClass; 88} 89 90try { 91 returnLoadedClass(); 92} catch (\TypeError $e) { 93 echo $e, PHP_EOL; 94} 95 96function returnLoadedInterface(): ?RealInterface { 97 return new \StdClass; 98} 99 100try { 101 returnLoadedInterface(); 102} catch (\TypeError $e) { 103 echo $e, PHP_EOL; 104} 105 106function returnUnloadedClassScalar(): ?I\Dont\Exist { 107 return 1; 108} 109 110try { 111 returnUnloadedClassScalar(); 112} catch (\TypeError $e) { 113 echo $e, PHP_EOL; 114} 115 116function returnLoadedClassScalar(): ?RealClass { 117 return 1; 118} 119 120try { 121 returnLoadedClassScalar(); 122} catch (\TypeError $e) { 123 echo $e, PHP_EOL; 124} 125 126function returnLoadedInterfaceScalar(): ?RealInterface { 127 return 1; 128} 129 130try { 131 returnLoadedInterfaceScalar(); 132} catch (\TypeError $e) { 133 echo $e, PHP_EOL; 134} 135 136function returnCallable(): ?callable { 137 return 1; 138} 139 140try { 141 returnCallable(); 142} catch (\TypeError $e) { 143 echo $e, PHP_EOL; 144} 145 146function returnIterable(): ?iterable { 147 return 1; 148} 149 150try { 151 returnIterable(); 152} catch (\TypeError $e) { 153 echo $e, PHP_EOL; 154} 155 156function returnInt(): ?int { 157 return new \StdClass; 158} 159 160try { 161 returnInt(); 162} catch (\TypeError $e) { 163 echo $e, PHP_EOL; 164} 165 166function returnMissingUnloadedClass(): ?I\Dont\Exist { 167} 168 169try { 170 returnMissingUnloadedClass(); 171} catch (\TypeError $e) { 172 echo $e, PHP_EOL; 173} 174 175function returnMissingLoadedClass(): ?RealClass { 176} 177 178try { 179 returnMissingLoadedClass(); 180} catch (\TypeError $e) { 181 echo $e, PHP_EOL; 182} 183 184function returnMissingLoadedInterface(): ?RealInterface { 185} 186 187try { 188 returnMissingLoadedInterface(); 189} catch (\TypeError $e) { 190 echo $e, PHP_EOL; 191} 192 193function returnMissingCallable(): ?callable { 194} 195 196try { 197 returnMissingCallable(); 198} catch (\TypeError $e) { 199 echo $e, PHP_EOL; 200} 201 202function returnMissingIterable(): ?iterable { 203} 204 205try { 206 returnMissingIterable(); 207} catch (\TypeError $e) { 208 echo $e, PHP_EOL; 209} 210 211function returnMissingInt(): ?int { 212} 213 214try { 215 returnMissingInt(); 216} catch (\TypeError $e) { 217 echo $e, PHP_EOL; 218} 219 220?> 221--EXPECTF-- 222TypeError: Argument 1 passed to unloadedClass() must be an instance of I\Dont\Exist or null, instance of stdClass given, called in %s on line 8 and defined in %s:5 223Stack trace: 224#0 %s(8): unloadedClass(Object(stdClass)) 225#1 {main} 226TypeError: Argument 1 passed to loadedClass() must be an instance of RealClass or null, instance of stdClass given, called in %s on line 20 and defined in %s:16 227Stack trace: 228#0 %s(20): loadedClass(Object(stdClass)) 229#1 {main} 230TypeError: Argument 1 passed to loadedInterface() must implement interface RealInterface or be null, instance of stdClass given, called in %s on line 26 and defined in %s:17 231Stack trace: 232#0 %s(26): loadedInterface(Object(stdClass)) 233#1 {main} 234TypeError: Argument 1 passed to unloadedClass() must be an instance of I\Dont\Exist or null, integer given, called in %s on line 32 and defined in %s:5 235Stack trace: 236#0 %s(32): unloadedClass(1) 237#1 {main} 238TypeError: Argument 1 passed to loadedClass() must be an instance of RealClass or null, integer given, called in %s on line 38 and defined in %s:16 239Stack trace: 240#0 %s(38): loadedClass(1) 241#1 {main} 242TypeError: Argument 1 passed to loadedInterface() must implement interface RealInterface or be null, integer given, called in %s on line 44 and defined in %s:17 243Stack trace: 244#0 %s(44): loadedInterface(1) 245#1 {main} 246TypeError: Argument 1 passed to callableF() must be callable or null, integer given, called in %s on line 52 and defined in %s:49 247Stack trace: 248#0 %s(52): callableF(1) 249#1 {main} 250TypeError: Argument 1 passed to iterableF() must be iterable or null, integer given, called in %s on line 60 and defined in %s:57 251Stack trace: 252#0 %s(60): iterableF(1) 253#1 {main} 254TypeError: Argument 1 passed to intF() must be of the type integer or null, object given, called in %s on line 68 and defined in %s:65 255Stack trace: 256#0 %s(68): intF(Object(stdClass)) 257#1 {main} 258TypeError: Return value of returnUnloadedClass() must be an instance of I\Dont\Exist or null, instance of stdClass returned in %s:74 259Stack trace: 260#0 %s(78): returnUnloadedClass() 261#1 {main} 262TypeError: Return value of returnLoadedClass() must be an instance of RealClass or null, instance of stdClass returned in %s:84 263Stack trace: 264#0 %s(88): returnLoadedClass() 265#1 {main} 266TypeError: Return value of returnLoadedInterface() must implement interface RealInterface or be null, instance of stdClass returned in %s:94 267Stack trace: 268#0 %s(98): returnLoadedInterface() 269#1 {main} 270TypeError: Return value of returnUnloadedClassScalar() must be an instance of I\Dont\Exist or null, integer returned in %s:104 271Stack trace: 272#0 %s(108): returnUnloadedClassScalar() 273#1 {main} 274TypeError: Return value of returnLoadedClassScalar() must be an instance of RealClass or null, integer returned in %s:114 275Stack trace: 276#0 %s(118): returnLoadedClassScalar() 277#1 {main} 278TypeError: Return value of returnLoadedInterfaceScalar() must implement interface RealInterface or be null, integer returned in %s:124 279Stack trace: 280#0 %s(128): returnLoadedInterfaceScalar() 281#1 {main} 282TypeError: Return value of returnCallable() must be callable or null, integer returned in %s:134 283Stack trace: 284#0 %s(138): returnCallable() 285#1 {main} 286TypeError: Return value of returnIterable() must be iterable or null, integer returned in %s:144 287Stack trace: 288#0 %s(148): returnIterable() 289#1 {main} 290TypeError: Return value of returnInt() must be of the type integer or null, object returned in %s:154 291Stack trace: 292#0 %s(158): returnInt() 293#1 {main} 294TypeError: Return value of returnMissingUnloadedClass() must be an instance of I\Dont\Exist or null, none returned in %s:164 295Stack trace: 296#0 %s(167): returnMissingUnloadedClass() 297#1 {main} 298TypeError: Return value of returnMissingLoadedClass() must be an instance of RealClass or null, none returned in %s:173 299Stack trace: 300#0 %s(176): returnMissingLoadedClass() 301#1 {main} 302TypeError: Return value of returnMissingLoadedInterface() must implement interface RealInterface or be null, none returned in %s:182 303Stack trace: 304#0 %s(185): returnMissingLoadedInterface() 305#1 {main} 306TypeError: Return value of returnMissingCallable() must be callable or null, none returned in %s:191 307Stack trace: 308#0 %s(194): returnMissingCallable() 309#1 {main} 310TypeError: Return value of returnMissingIterable() must be iterable or null, none returned in %s:200 311Stack trace: 312#0 %s(203): returnMissingIterable() 313#1 {main} 314TypeError: Return value of returnMissingInt() must be of the type integer or null, none returned in %s:209 315Stack trace: 316#0 %s(212): returnMissingInt() 317#1 {main} 318