@@ -6218,6 +6218,44 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
6218
6218
}
6219
6219
}
6220
6220
6221
+ static void zend_is_intersection_redundant_with_intersection (const zend_type a , const zend_type b )
6222
+ {
6223
+ zend_type outer ;
6224
+ zend_type inner ;
6225
+ zend_type * single_outer ;
6226
+ zend_type * single_inner ;
6227
+
6228
+ if (ZEND_TYPE_LIST (b )-> num_types < ZEND_TYPE_LIST (a )-> num_types ) {
6229
+ outer = b ;
6230
+ inner = a ;
6231
+ } else {
6232
+ outer = a ;
6233
+ inner = b ;
6234
+ }
6235
+
6236
+ /* As outer is the intersection type with the least number of types,
6237
+ * it means that it is only redundant if all types of it are found in inner */
6238
+ ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (outer ), single_outer ) {
6239
+ bool is_found = false;
6240
+ ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (inner ), single_inner ) {
6241
+ if (zend_string_equals_ci (ZEND_TYPE_NAME (* single_outer ), ZEND_TYPE_NAME (* single_inner ))) {
6242
+ is_found = true;
6243
+ break ;
6244
+ }
6245
+ } ZEND_TYPE_LIST_FOREACH_END ();
6246
+ /* Type not found in inner, thus cannot be redundant */
6247
+ if (!is_found ) {
6248
+ return ;
6249
+ }
6250
+ } ZEND_TYPE_LIST_FOREACH_END ();
6251
+
6252
+ /* Type is redundant */
6253
+ zend_string * inner_type_str = zend_type_to_string (inner );
6254
+ zend_string * outer_type_str = zend_type_to_string (outer );
6255
+ zend_error_noreturn (E_COMPILE_ERROR ,
6256
+ "Type %s is redundant with %s" , ZSTR_VAL (inner_type_str ), ZSTR_VAL (outer_type_str ));
6257
+ }
6258
+
6221
6259
static zend_type zend_compile_typename (
6222
6260
zend_ast * ast , bool force_allow_null ) /* {{{ */
6223
6261
{
@@ -6258,7 +6296,28 @@ static zend_type zend_compile_typename(
6258
6296
6259
6297
type_list -> types [type_list -> num_types ++ ] = single_type ;
6260
6298
6261
- /* TODO Check for trivially redundant class types? */
6299
+ /* Check for trivially redundant class types */
6300
+ zend_type * individual_intersection_type ;
6301
+ for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6302
+ if (ZEND_TYPE_HAS_LIST (type_list -> types [i ])) {
6303
+ ZEND_ASSERT (ZEND_TYPE_IS_INTERSECTION (type_list -> types [i ]));
6304
+ zend_is_intersection_redundant_with_intersection (single_type , type_list -> types [i ]);
6305
+ continue ;
6306
+ }
6307
+ ZEND_ASSERT (ZEND_TYPE_HAS_NAME (type_list -> types [i ]));
6308
+
6309
+ ZEND_TYPE_FOREACH (single_type , individual_intersection_type ) {
6310
+ ZEND_ASSERT (ZEND_TYPE_HAS_NAME (* individual_intersection_type ));
6311
+ if (zend_string_equals_ci ( ZEND_TYPE_NAME (type_list -> types [i ]),
6312
+ ZEND_TYPE_NAME (* individual_intersection_type ))) {
6313
+ zend_string * single_type_str = zend_type_to_string (single_type );
6314
+ zend_string * duplicate_type_str = zend_type_to_string (* individual_intersection_type );
6315
+ zend_error_noreturn (E_COMPILE_ERROR ,
6316
+ "Type %s is redundant with %s" , ZSTR_VAL (single_type_str ),
6317
+ ZSTR_VAL (duplicate_type_str ));
6318
+ }
6319
+ } ZEND_TYPE_FOREACH_END ();
6320
+ }
6262
6321
continue ;
6263
6322
}
6264
6323
@@ -6298,6 +6357,18 @@ static zend_type zend_compile_typename(
6298
6357
/* Check for trivially redundant class types */
6299
6358
for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6300
6359
if (ZEND_TYPE_IS_INTERSECTION (type_list -> types [i ])) {
6360
+ zend_type * individual_intersection_type ;
6361
+ ZEND_TYPE_FOREACH (type_list -> types [i ], individual_intersection_type ) {
6362
+ ZEND_ASSERT (ZEND_TYPE_HAS_NAME (* individual_intersection_type ));
6363
+ if (zend_string_equals_ci (ZEND_TYPE_NAME (single_type ),
6364
+ ZEND_TYPE_NAME (* individual_intersection_type ))) {
6365
+ zend_string * single_type_str = zend_type_to_string (single_type );
6366
+ zend_string * intersection_str = zend_type_to_string (type_list -> types [i ]);
6367
+ zend_error_noreturn (E_COMPILE_ERROR ,
6368
+ "Type %s is redundant with %s" , ZSTR_VAL (intersection_str ),
6369
+ ZSTR_VAL (single_type_str ));
6370
+ }
6371
+ } ZEND_TYPE_FOREACH_END ();
6301
6372
continue ;
6302
6373
}
6303
6374
if (zend_string_equals_ci (
0 commit comments