kphp
kphp copied to clipboard
Add the ability to cast an object to `mixed` type
<?php
class A { }
function foo(mixed $x) {
if ($x instanceof A) {
echo "A" . "\n";
}
else {
echo "Not A" . "\n";
}
}
foo(new A);
foo(42);
For now, KPHP shows the following error:
Compilation error at stage: Calc actual calls, gen by type-inferer.cpp:53
index.php:5 in foo
if ($x instanceof A) {
pass mixed to argument $instance of instance_cast
but it's declared as @param object
index.php:5 in foo
if ($x instanceof A) {
$x is mixed
index.php:4 in foo
function foo(mixed $x) {
argument $x declared as mixed
This functionality assumes two tasks:
- Track all the places where object is cast to mixed
- Change the mixed implementation
Talking about mixed implementation, we should add OBJECT
value to mixed::type
.
In layout: mixed.storage
should contain a pointer to an object.
Key note: for all classes, that are cast to mixed
, we should generate the following code(A
class from previous snippet:
struct VirtualBaseForMixedClass { virtual ~VirtualBaseForMixedClass() = default; };
...
struct C$A : VirtualBaseForMixedClass { ~C$A() {} };
It will allow us to do the following:
$x instanceof A
--> (pseudocode)
auto* $tmp = dynamic_cast<rhs.as_instanceof()::class_type *>(reinterpret_cast<VirtualBaseForMixedClass*>(lhs.as_mixed().storage))
if ($tmp == nullptr) { error(...) }
But why? The fact that a class instance cannot be mixed
was a fundamental statement for KPHP for years, why break this rule now?
But why? The fact that a class instance cannot be
mixed
was a fundamental statement for KPHP for years, why break this rule now?
It allows a bigger subset of PHP to be compiled. But for now it's only idea about its implementation in runtime, not about type system.