Skip to content

Commit f28307c

Browse files
committed
IT WORKS
Currently crappy boolean value to make sure first single class type doesn't use the void* to store the CE
1 parent 8fe285e commit f28307c

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

Zend/tests/type_declarations/composite_types/intersection_and_union_type_combined.phpt

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ interface Y {}
88

99
class A implements X, Y {}
1010
class B {}
11+
class C {}
1112

1213
class Test {
1314
public X&Y|int $prop1;
@@ -50,13 +51,77 @@ $test->prop2 = $i;
5051
$test->bar1($a);
5152
$test->bar2($a);
5253
$test->bar1($b);
53-
$test->bar2($b); // This currently fails
54+
$test->bar2($b);
5455
$test->prop3 = $a;
5556
$test->prop4 = $b;
5657
$test->prop3 = $a;
5758
$test->prop4 = $b;
5859

60+
$c = new C();
61+
try {
62+
$test->foo1($c);
63+
} catch (\TypeError $e) {
64+
echo $e->getMessage(), \PHP_EOL;
65+
}
66+
try {
67+
$test->foo2($c);
68+
} catch (\TypeError $e) {
69+
echo $e->getMessage(), \PHP_EOL;
70+
}
71+
try {
72+
$test->bar1($c);
73+
} catch (\TypeError $e) {
74+
echo $e->getMessage(), \PHP_EOL;
75+
}
76+
try {
77+
$test->bar2($c);
78+
} catch (\TypeError $e) {
79+
echo $e->getMessage(), \PHP_EOL;
80+
}
81+
try {
82+
$test->prop1 = $c;
83+
} catch (\TypeError $e) {
84+
echo $e->getMessage(), \PHP_EOL;
85+
}
86+
try {
87+
$test->prop2 = $c;
88+
} catch (\TypeError $e) {
89+
echo $e->getMessage(), \PHP_EOL;
90+
}
91+
try {
92+
$test->prop3 = $c;
93+
} catch (\TypeError $e) {
94+
echo $e->getMessage(), \PHP_EOL;
95+
}
96+
try {
97+
$test->prop4 = $c;
98+
} catch (\TypeError $e) {
99+
echo $e->getMessage(), \PHP_EOL;
100+
}
101+
59102
?>
60103
===DONE===
61-
--EXPECT--
104+
--EXPECTF--
105+
object(A)#2 (0) {
106+
}
107+
object(A)#2 (0) {
108+
}
109+
int(10)
110+
int(10)
111+
object(A)#2 (0) {
112+
}
113+
object(A)#2 (0) {
114+
}
115+
object(B)#3 (0) {
116+
}
117+
object(B)#3 (0) {
118+
}
119+
Test::foo1(): Argument #1 ($v) must be of type X&Y|int, C given, called in %s on line %d
120+
Test::foo2(): Argument #1 ($v) must be of type X&Y|int, C given, called in %s on line %d
121+
Test::bar1(): Argument #1 ($v) must be of type B|X&Y, C given, called in %s on line %d
122+
Test::bar2(): Argument #1 ($v) must be of type X&Y|B, C given, called in %s on line %d
123+
Cannot assign C to property Test::$prop1 of type X&Y|int
124+
Cannot assign C to property Test::$prop2 of type X&Y|int
125+
Cannot assign C to property Test::$prop3 of type X&Y|B
126+
Cannot assign C to property Test::$prop4 of type B|X&Y
62127
===DONE===

Zend/zend_compile.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6276,6 +6276,7 @@ static zend_type zend_compile_typename(
62766276
if (ast->kind == ZEND_AST_TYPE_UNION) {
62776277
zend_ast_list *list = zend_ast_get_list(ast);
62786278
zend_type_list *type_list;
6279+
bool is_composite = false;
62796280
ALLOCA_FLAG(use_heap)
62806281

62816282
type_list = do_alloca(ZEND_TYPE_LIST_SIZE(list->children), use_heap);
@@ -6287,6 +6288,7 @@ static zend_type zend_compile_typename(
62876288
uint32_t single_type_mask;
62886289

62896290
if (type_ast->kind == ZEND_AST_TYPE_INTERSECTION) {
6291+
is_composite = true;
62906292
/* The first class type can be stored directly as the type ptr payload. */
62916293
if (ZEND_TYPE_IS_COMPLEX(type) && !ZEND_TYPE_HAS_LIST(type)) {
62926294
/* Switch from single name to name list. */
@@ -6324,7 +6326,7 @@ static zend_type zend_compile_typename(
63246326
ZEND_TYPE_FULL_MASK(single_type) &= ~_ZEND_TYPE_MAY_BE_MASK;
63256327

63266328
if (ZEND_TYPE_IS_COMPLEX(single_type)) {
6327-
if (!ZEND_TYPE_IS_COMPLEX(type)) {
6329+
if (!ZEND_TYPE_IS_COMPLEX(type) && !is_composite) {
63286330
/* The first class type can be stored directly as the type ptr payload. */
63296331
ZEND_TYPE_SET_PTR(type, ZEND_TYPE_NAME(single_type));
63306332
ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_NAME_BIT;

0 commit comments

Comments
 (0)