Skip to content

Commit 47a64f5

Browse files
committed
Handle union&intersection types in the same loop for typed properties
1 parent 44822a1 commit 47a64f5

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
@@ -846,74 +846,49 @@ static zend_class_entry *resolve_single_class_type(zend_string *name, zend_class
846846
}
847847

848848
// TODO Handle complex types when added
849-
// TODO Update to handle union and intersection in the same loop
850849
static bool zend_check_and_resolve_property_class_type(
851850
zend_property_info *info, zend_class_entry *object_ce) {
852851
zend_class_entry *ce;
853852
if (ZEND_TYPE_HAS_LIST(info->type)) {
854853
zend_type *list_type;
854+
bool has_intersection = ZEND_TYPE_HAS_INTERSECTION(info->type);
855855

856-
if (ZEND_TYPE_HAS_INTERSECTION(info->type)) {
857-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(info->type), list_type) {
858-
if (ZEND_TYPE_HAS_NAME(*list_type)) {
859-
if (ZEND_TYPE_HAS_CE_CACHE(*list_type)) {
860-
ce = ZEND_TYPE_CE_CACHE(*list_type);
861-
if (!ce) {
862-
zend_string *name = ZEND_TYPE_NAME(*list_type);
863-
ce = resolve_single_class_type(name, info->ce);
864-
if (UNEXPECTED(!ce)) {
865-
continue;
866-
}
867-
ZEND_TYPE_SET_CE_CACHE(*list_type, ce);
868-
}
869-
} else {
856+
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(info->type), list_type) {
857+
if (ZEND_TYPE_HAS_NAME(*list_type)) {
858+
if (ZEND_TYPE_HAS_CE_CACHE(*list_type)) {
859+
ce = ZEND_TYPE_CE_CACHE(*list_type);
860+
if (!ce) {
870861
zend_string *name = ZEND_TYPE_NAME(*list_type);
871862
ce = resolve_single_class_type(name, info->ce);
872-
if (!ce) {
863+
if (UNEXPECTED(!ce)) {
873864
continue;
874865
}
875-
zend_string_release(name);
876-
ZEND_TYPE_SET_CE(*list_type, ce);
866+
ZEND_TYPE_SET_CE_CACHE(*list_type, ce);
877867
}
878868
} else {
879-
ce = ZEND_TYPE_CE(*list_type);
869+
zend_string *name = ZEND_TYPE_NAME(*list_type);
870+
ce = resolve_single_class_type(name, info->ce);
871+
if (!ce) {
872+
continue;
873+
}
874+
zend_string_release(name);
875+
ZEND_TYPE_SET_CE(*list_type, ce);
880876
}
877+
} else {
878+
ce = ZEND_TYPE_CE(*list_type);
879+
}
880+
if (UNEXPECTED(has_intersection)) {
881881
if (!instanceof_function(object_ce, ce)) {
882882
return false;
883883
}
884-
} ZEND_TYPE_LIST_FOREACH_END();
885-
return true;
886-
} else {
887-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(info->type), list_type) {
888-
if (ZEND_TYPE_HAS_NAME(*list_type)) {
889-
if (ZEND_TYPE_HAS_CE_CACHE(*list_type)) {
890-
ce = ZEND_TYPE_CE_CACHE(*list_type);
891-
if (!ce) {
892-
zend_string *name = ZEND_TYPE_NAME(*list_type);
893-
ce = resolve_single_class_type(name, info->ce);
894-
if (UNEXPECTED(!ce)) {
895-
continue;
896-
}
897-
ZEND_TYPE_SET_CE_CACHE(*list_type, ce);
898-
}
899-
} else {
900-
zend_string *name = ZEND_TYPE_NAME(*list_type);
901-
ce = resolve_single_class_type(name, info->ce);
902-
if (!ce) {
903-
continue;
904-
}
905-
zend_string_release(name);
906-
ZEND_TYPE_SET_CE(*list_type, ce);
907-
}
908-
} else {
909-
ce = ZEND_TYPE_CE(*list_type);
910-
}
911-
if (instanceof_function(object_ce, ce)) {
912-
return 1;
913-
}
914-
} ZEND_TYPE_LIST_FOREACH_END();
915-
return 0;
916-
}
884+
} else if (instanceof_function(object_ce, ce)) {
885+
return true;
886+
}
887+
} ZEND_TYPE_LIST_FOREACH_END();
888+
/* If type is an intersection reaching the end of the loop
889+
* means the type has validated, for union types it means
890+
* it has failed */
891+
return has_intersection;
917892
} else {
918893
if (UNEXPECTED(ZEND_TYPE_HAS_NAME(info->type))) {
919894
if (ZEND_TYPE_HAS_CE_CACHE(info->type)) {

0 commit comments

Comments
 (0)