diff --git a/ChangeLog.md b/ChangeLog.md index cbad2d6a..845a5ca5 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -3,6 +3,13 @@ XP Compiler ChangeLog ## ?.?.? / ????-??-?? +## 8.17.2 / 2024-03-23 + +* Fixed *implicitely nullable type* warnings for parameters with non- + constant expressions (e.g. `$param= new Handle(0)`) in PHP 8.4, see + https://wiki.php.net/rfc/deprecate-implicitly-nullable-types + (@thekid) + ## 8.17.1 / 2024-01-06 * Fixed emitting captures and return types for closures - @thekid diff --git a/src/main/php/lang/ast/emit/PHP.class.php b/src/main/php/lang/ast/emit/PHP.class.php index fe08e57e..1a73e1ae 100755 --- a/src/main/php/lang/ast/emit/PHP.class.php +++ b/src/main/php/lang/ast/emit/PHP.class.php @@ -297,24 +297,35 @@ protected function emitArray($result, $array) { } protected function emitParameter($result, $parameter) { + $result->locals[$parameter->name]= true; $parameter->annotations && $this->emitOne($result, $parameter->annotations); - if ($parameter->type && $t= $this->literal($parameter->type)) { - $result->out->write($t.' '); + + // If we have a non-constant default and a type, emit a nullable type hint + // to prevent "implicitely nullable type" warnings being raised. See here: + // https://wiki.php.net/rfc/deprecate-implicitly-nullable-types + $type= $parameter->type; + if ($parameter->default) { + $const= $this->isConstant($result, $parameter->default); + if ($type && !$const && !$type instanceof IsNullable) { + $type= new IsNullable($parameter->type); + } } + if ($type && $t= $this->literal($type)) $result->out->write($t.' '); + if ($parameter->variadic) { $result->out->write('... $'.$parameter->name); } else { $result->out->write(($parameter->reference ? '&' : '').'$'.$parameter->name); } + if ($parameter->default) { - if ($this->isConstant($result, $parameter->default)) { + if ($const) { $result->out->write('='); $this->emitOne($result, $parameter->default); } else { $result->out->write('=null'); } } - $result->locals[$parameter->name]= true; } protected function emitSignature($result, $signature, $use= null) {