Skip to content

Commit 1164585

Browse files
committed
Handle union&intersection types in the same loop for typed properties
1 parent ed3b2ea commit 1164585

File tree

1 file changed

+27
-52
lines changed

1 file changed

+27
-52
lines changed

Zend/zend_execute.c

Lines changed: 27 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -852,74 +852,49 @@ static zend_class_entry *resolve_single_class_type(zend_string *name, zend_class
852852
}
853853

854854
// TODO Handle complex types when added
855-
// TODO Update to handle union and intersection in the same loop
856855
static bool zend_check_and_resolve_property_class_type(
857856
zend_property_info *info, zend_class_entry *object_ce) {
858857
zend_class_entry *ce;
859858
if (ZEND_TYPE_HAS_LIST(info->type)) {
860859
zend_type *list_type;
860+
bool has_intersection = ZEND_TYPE_HAS_INTERSECTION(info->type);
861861

862-
if (ZEND_TYPE_HAS_INTERSECTION(info->type)) {
863-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(info->type), list_type) {
864-
if (ZEND_TYPE_HAS_NAME(*list_type)) {
865-
if (ZEND_TYPE_HAS_CE_CACHE(*list_type)) {
866-
ce = ZEND_TYPE_CE_CACHE(*list_type);
867-
if (!ce) {
868-
zend_string *name = ZEND_TYPE_NAME(*list_type);
869-
ce = resolve_single_class_type(name, info->ce);
870-
if (UNEXPECTED(!ce)) {
871-
continue;
872-
}
873-
ZEND_TYPE_SET_CE_CACHE(*list_type, ce);
874-
}
875-
} else {
862+
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(info->type), list_type) {
863+
if (ZEND_TYPE_HAS_NAME(*list_type)) {
864+
if (ZEND_TYPE_HAS_CE_CACHE(*list_type)) {
865+
ce = ZEND_TYPE_CE_CACHE(*list_type);
866+
if (!ce) {
876867
zend_string *name = ZEND_TYPE_NAME(*list_type);
877868
ce = resolve_single_class_type(name, info->ce);
878-
if (!ce) {
869+
if (UNEXPECTED(!ce)) {
879870
continue;
880871
}
881-
zend_string_release(name);
882-
ZEND_TYPE_SET_CE(*list_type, ce);
872+
ZEND_TYPE_SET_CE_CACHE(*list_type, ce);
883873
}
884874
} else {
885-
ce = ZEND_TYPE_CE(*list_type);
875+
zend_string *name = ZEND_TYPE_NAME(*list_type);
876+
ce = resolve_single_class_type(name, info->ce);
877+
if (!ce) {
878+
continue;
879+
}
880+
zend_string_release(name);
881+
ZEND_TYPE_SET_CE(*list_type, ce);
886882
}
883+
} else {
884+
ce = ZEND_TYPE_CE(*list_type);
885+
}
886+
if (UNEXPECTED(has_intersection)) {
887887
if (!instanceof_function(object_ce, ce)) {
888888
return false;
889889
}
890-
} ZEND_TYPE_LIST_FOREACH_END();
891-
return true;
892-
} else {
893-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(info->type), list_type) {
894-
if (ZEND_TYPE_HAS_NAME(*list_type)) {
895-
if (ZEND_TYPE_HAS_CE_CACHE(*list_type)) {
896-
ce = ZEND_TYPE_CE_CACHE(*list_type);
897-
if (!ce) {
898-
zend_string *name = ZEND_TYPE_NAME(*list_type);
899-
ce = resolve_single_class_type(name, info->ce);
900-
if (UNEXPECTED(!ce)) {
901-
continue;
902-
}
903-
ZEND_TYPE_SET_CE_CACHE(*list_type, ce);
904-
}
905-
} else {
906-
zend_string *name = ZEND_TYPE_NAME(*list_type);
907-
ce = resolve_single_class_type(name, info->ce);
908-
if (!ce) {
909-
continue;
910-
}
911-
zend_string_release(name);
912-
ZEND_TYPE_SET_CE(*list_type, ce);
913-
}
914-
} else {
915-
ce = ZEND_TYPE_CE(*list_type);
916-
}
917-
if (instanceof_function(object_ce, ce)) {
918-
return 1;
919-
}
920-
} ZEND_TYPE_LIST_FOREACH_END();
921-
return 0;
922-
}
890+
} else if (instanceof_function(object_ce, ce)) {
891+
return true;
892+
}
893+
} ZEND_TYPE_LIST_FOREACH_END();
894+
/* If type is an intersection reaching the end of the loop
895+
* means the type has validated, for union types it means
896+
* it has failed */
897+
return has_intersection;
923898
} else {
924899
if (UNEXPECTED(ZEND_TYPE_HAS_NAME(info->type))) {
925900
if (ZEND_TYPE_HAS_CE_CACHE(info->type)) {

0 commit comments

Comments
 (0)