On 02/06/2025 17:27, Gina P. Banyard wrote:
The objective is to fix a weird quirk of PHP's type system, where void lives in
its own type hierarchy.
This is visible mainly in that a lack of return type is not isomorphic to a
function that has a return type of mixed.
I think if "void" was added now, it would be an attribute, rather than a
type. It is in effect the exact opposite of #[\NoDiscard], and
distinguishes between these two cases:
interface Foo {
public function getSomething(): ?Something;
}
class MyFoo implements Foo {
public function getSomething(): null {
// My result is always null, but still meaningful to consumers
of the Foo interface
return null;
}
#[\DiscardReturn]
public function doSomething(): null {
// I have no meaningful information to return; any assignment
of my implicit value is a mistake
}
}
I agree the type hierarchy you describe is weird, but rather than
throwing away the functionality completely, I wonder if we can make it
more consistent:
- Make "no return type declared" and "mixed" equivalent
- Make "void" a sub-type of "null", and therefore a sub-type of "mixed"
If I've got that right, this would then be legal:
class A{ public function foo() {} } class B extends A{ public function foo():
mixed{} }
class C extends B{ public function foo(): null{} }
class D extends C{ public function foo(): void{} }
class E extends D{ public function foo(): never {} }
That seems reasonable enough; I may have missed something important, though.
Regards,
--
Rowan Tommins
[IMSoP]