@@ -446,6 +446,7 @@ static inheritance_status zend_perform_intersection_covariant_class_type_check(
446
446
return have_unresolved ? INHERITANCE_UNRESOLVED : INHERITANCE_ERROR ;
447
447
}
448
448
449
+ /* Check whether a single class proto type is a subtype of a potentially complex fe_type. */
449
450
static inheritance_status zend_perform_covariant_class_type_check (
450
451
zend_class_entry * fe_scope , zend_string * fe_class_name , zend_class_entry * fe_ce ,
451
452
zend_class_entry * proto_scope , zend_type proto_type ,
@@ -478,15 +479,19 @@ static inheritance_status zend_perform_covariant_class_type_check(
478
479
zend_type * single_type ;
479
480
480
481
/* Traverse the list of parent types and check if the current child (FE)
481
- * class is the subtype of at least one of them */
482
+ * class is the subtype of at least one of them (union) or all of them (intersection). */
483
+ bool is_intersection = ZEND_TYPE_IS_INTERSECTION (proto_type );
482
484
ZEND_TYPE_FOREACH (proto_type , single_type ) {
483
485
zend_class_entry * proto_ce ;
484
486
zend_string * proto_class_name = NULL ;
485
487
if (ZEND_TYPE_HAS_NAME (* single_type )) {
486
488
proto_class_name =
487
489
resolve_class_name (proto_scope , ZEND_TYPE_NAME (* single_type ));
488
490
if (zend_string_equals_ci (fe_class_name , proto_class_name )) {
489
- return INHERITANCE_SUCCESS ;
491
+ if (!is_intersection ) {
492
+ return INHERITANCE_SUCCESS ;
493
+ }
494
+ continue ;
490
495
}
491
496
492
497
if (!fe_ce ) fe_ce = lookup_class (fe_scope , fe_class_name , register_unresolved );
@@ -497,69 +502,31 @@ static inheritance_status zend_perform_covariant_class_type_check(
497
502
proto_ce = ZEND_TYPE_CE (* single_type );
498
503
} else {
499
504
/* standard type */
505
+ ZEND_ASSERT (!is_intersection );
500
506
continue ;
501
507
}
502
508
503
509
if (!fe_ce || !proto_ce ) {
504
510
have_unresolved = 1 ;
505
- } else if (unlinked_instanceof (fe_ce , proto_ce )) {
511
+ continue ;
512
+ }
513
+ if (unlinked_instanceof (fe_ce , proto_ce )) {
506
514
track_class_dependency (fe_ce , fe_class_name );
507
515
track_class_dependency (proto_ce , proto_class_name );
508
- return INHERITANCE_SUCCESS ;
509
- }
510
- } ZEND_TYPE_FOREACH_END ();
511
-
512
- return have_unresolved ? INHERITANCE_UNRESOLVED : INHERITANCE_ERROR ;
513
- }
514
-
515
- /* checks that the child type (being unique) is a subtype of each member of the parent intersection */
516
- static inheritance_status zend_is_single_type_subtype_intersection (
517
- zend_class_entry * fe_scope , zend_string * fe_class_name ,
518
- zend_class_entry * fe_ce , zend_class_entry * proto_scope ,
519
- zend_type proto_type , bool register_unresolved
520
- ) {
521
- bool have_unresolved = false;
522
- zend_type * single_type ;
523
- zend_type_list * parent_intersection_types ;
524
-
525
- ZEND_ASSERT (ZEND_TYPE_IS_INTERSECTION (proto_type ));
526
-
527
- parent_intersection_types = ZEND_TYPE_LIST (proto_type );
528
-
529
- ZEND_TYPE_LIST_FOREACH (parent_intersection_types , single_type ) {
530
- zend_class_entry * proto_ce ;
531
- zend_string * proto_class_name = NULL ;
532
- if (ZEND_TYPE_HAS_NAME (* single_type )) {
533
- proto_class_name =
534
- resolve_class_name (proto_scope , ZEND_TYPE_NAME (* single_type ));
535
- if (zend_string_equals_ci (fe_class_name , proto_class_name )) {
536
- continue ;
516
+ if (!is_intersection ) {
517
+ return INHERITANCE_SUCCESS ;
537
518
}
538
-
539
- if (!fe_ce ) fe_ce = lookup_class (fe_scope , fe_class_name , register_unresolved );
540
- proto_ce = lookup_class (proto_scope , proto_class_name , register_unresolved );
541
- } else if (ZEND_TYPE_HAS_CE (* single_type )) {
542
- if (!fe_ce ) fe_ce = lookup_class (fe_scope , fe_class_name , register_unresolved );
543
- proto_ce = ZEND_TYPE_CE (* single_type );
544
519
} else {
545
- /* standard type cannot be part a subtype of an intersection type */
546
- ZEND_UNREACHABLE ();
547
- continue ;
548
- }
549
-
550
- if (!fe_ce || !proto_ce ) {
551
- have_unresolved = true;
552
- continue ;
553
- }
554
- if (!unlinked_instanceof (fe_ce , proto_ce )) {
555
- return INHERITANCE_ERROR ;
520
+ if (is_intersection ) {
521
+ return INHERITANCE_ERROR ;
522
+ }
556
523
}
524
+ } ZEND_TYPE_FOREACH_END ();
557
525
558
- track_class_dependency (fe_ce , fe_class_name );
559
- track_class_dependency (proto_ce , proto_class_name );
560
- } ZEND_TYPE_LIST_FOREACH_END ();
561
-
562
- return have_unresolved ? INHERITANCE_UNRESOLVED : INHERITANCE_SUCCESS ;
526
+ if (have_unresolved ) {
527
+ return INHERITANCE_UNRESOLVED ;
528
+ }
529
+ return is_intersection ? INHERITANCE_SUCCESS : INHERITANCE_ERROR ;
563
530
}
564
531
565
532
static inheritance_status zend_perform_covariant_type_check (
@@ -682,16 +649,9 @@ static inheritance_status zend_perform_covariant_type_check(
682
649
continue ;
683
650
}
684
651
685
- if (UNEXPECTED (ZEND_TYPE_IS_INTERSECTION (proto_type ))) {
686
- status = zend_is_single_type_subtype_intersection (fe_scope ,
687
- fe_class_name , fe_ce , proto_scope , proto_type ,
688
- /* register_unresolved */ false);
689
- } else {
690
- status = zend_perform_covariant_class_type_check (fe_scope ,
691
- fe_class_name , fe_ce , proto_scope , proto_type ,
692
- /* register_unresolved */ false);
693
- }
694
-
652
+ status = zend_perform_covariant_class_type_check (fe_scope ,
653
+ fe_class_name , fe_ce , proto_scope , proto_type ,
654
+ /* register_unresolved */ false);
695
655
if (status == INHERITANCE_ERROR ) {
696
656
return INHERITANCE_ERROR ;
697
657
}
@@ -741,15 +701,9 @@ static inheritance_status zend_perform_covariant_type_check(
741
701
continue ;
742
702
}
743
703
744
- if (UNEXPECTED (ZEND_TYPE_IS_INTERSECTION (proto_type ))) {
745
- zend_is_single_type_subtype_intersection (fe_scope ,
746
- fe_class_name , fe_ce , proto_scope , proto_type ,
747
- /* register_unresolved */ true);
748
- } else {
749
- zend_perform_covariant_class_type_check (fe_scope ,
750
- fe_class_name , fe_ce , proto_scope , proto_type ,
751
- /* register_unresolved */ true);
752
- }
704
+ zend_perform_covariant_class_type_check (fe_scope ,
705
+ fe_class_name , fe_ce , proto_scope , proto_type ,
706
+ /* register_unresolved */ true);
753
707
} ZEND_TYPE_FOREACH_END ();
754
708
}
755
709
return INHERITANCE_UNRESOLVED ;
0 commit comments