@@ -6226,6 +6226,91 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
6226
6226
}
6227
6227
}
6228
6228
6229
+ static void zend_are_intersection_types_redundant (zend_type left_type , zend_type right_type )
6230
+ {
6231
+ ZEND_ASSERT (ZEND_TYPE_IS_INTERSECTION (left_type ));
6232
+ ZEND_ASSERT (ZEND_TYPE_IS_INTERSECTION (right_type ));
6233
+ zend_type_list * l_type_list = ZEND_TYPE_LIST (left_type );
6234
+ zend_type_list * r_type_list = ZEND_TYPE_LIST (right_type );
6235
+ zend_type_list * smaller_type_list , * larger_type_list ;
6236
+ bool flipped = false;
6237
+
6238
+ if (r_type_list -> num_types < l_type_list -> num_types ) {
6239
+ smaller_type_list = r_type_list ;
6240
+ larger_type_list = l_type_list ;
6241
+ flipped = true;
6242
+ } else {
6243
+ smaller_type_list = l_type_list ;
6244
+ larger_type_list = r_type_list ;
6245
+ }
6246
+
6247
+ int sum = 0 ;
6248
+ zend_type * outer_type ;
6249
+ ZEND_TYPE_LIST_FOREACH (smaller_type_list , outer_type )
6250
+ zend_type * inner_type ;
6251
+ ZEND_TYPE_LIST_FOREACH (larger_type_list , inner_type )
6252
+ if (zend_string_equals_ci (ZEND_TYPE_NAME (* inner_type ), ZEND_TYPE_NAME (* outer_type ))) {
6253
+ sum ++ ;
6254
+ break ;
6255
+ }
6256
+ ZEND_TYPE_LIST_FOREACH_END ();
6257
+ ZEND_TYPE_LIST_FOREACH_END ();
6258
+
6259
+ if (sum == smaller_type_list -> num_types ) {
6260
+ zend_string * l_type_str = zend_type_to_string (left_type );
6261
+ zend_string * r_type_str = zend_type_to_string (right_type );
6262
+ if (smaller_type_list -> num_types == larger_type_list -> num_types ) {
6263
+ if (flipped ) {
6264
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is redundant with type %s" ,
6265
+ ZSTR_VAL (r_type_str ), ZSTR_VAL (l_type_str ));
6266
+ } else {
6267
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is redundant with type %s" ,
6268
+ ZSTR_VAL (l_type_str ), ZSTR_VAL (r_type_str ));
6269
+ }
6270
+ } else {
6271
+ if (flipped ) {
6272
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is less restrictive than type %s" ,
6273
+ ZSTR_VAL (r_type_str ), ZSTR_VAL (l_type_str ));
6274
+ } else {
6275
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is less restrictive than type %s" ,
6276
+ ZSTR_VAL (l_type_str ), ZSTR_VAL (r_type_str ));
6277
+ }
6278
+ }
6279
+ }
6280
+ }
6281
+
6282
+ static void zend_is_intersection_type_redundant_by_single_type (zend_type intersection_type , zend_type single_type )
6283
+ {
6284
+ ZEND_ASSERT (ZEND_TYPE_IS_INTERSECTION (intersection_type ));
6285
+ ZEND_ASSERT (!ZEND_TYPE_IS_INTERSECTION (single_type ));
6286
+
6287
+ zend_type * single_intersection_type = NULL ;
6288
+ ZEND_TYPE_FOREACH (intersection_type , single_intersection_type )
6289
+ if (zend_string_equals_ci (ZEND_TYPE_NAME (* single_intersection_type ), ZEND_TYPE_NAME (single_type ))) {
6290
+ zend_string * single_type_str = zend_type_to_string (single_type );
6291
+ zend_string * complete_type = zend_type_to_string (intersection_type );
6292
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is less restrictive than type %s" ,
6293
+ ZSTR_VAL (single_type_str ), ZSTR_VAL (complete_type ));
6294
+ }
6295
+ ZEND_TYPE_FOREACH_END ();
6296
+ }
6297
+
6298
+ /* Used by both intersection and union types prior to transforming the type list to a full zend_type */
6299
+ static void zend_is_type_list_redundant_by_single_type (zend_type_list * type_list , zend_type type )
6300
+ {
6301
+ ZEND_ASSERT (!ZEND_TYPE_IS_INTERSECTION (type ));
6302
+ for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6303
+ if (ZEND_TYPE_IS_INTERSECTION (type_list -> types [i ])) {
6304
+ zend_is_intersection_type_redundant_by_single_type (type_list -> types [i ], type );
6305
+ continue ;
6306
+ }
6307
+ if (zend_string_equals_ci (ZEND_TYPE_NAME (type_list -> types [i ]), ZEND_TYPE_NAME (type ))) {
6308
+ zend_string * single_type_str = zend_type_to_string (type );
6309
+ zend_error_noreturn (E_COMPILE_ERROR , "Duplicate type %s is redundant" , ZSTR_VAL (single_type_str ));
6310
+ }
6311
+ }
6312
+ }
6313
+
6229
6314
static zend_type zend_compile_typename (
6230
6315
zend_ast * ast , bool force_allow_null ) /* {{{ */
6231
6316
{
@@ -6266,7 +6351,15 @@ static zend_type zend_compile_typename(
6266
6351
6267
6352
type_list -> types [type_list -> num_types ++ ] = single_type ;
6268
6353
6269
- /* TODO Check for trivially redundant class types? */
6354
+ /* Check for trivially redundant class types */
6355
+ for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6356
+ if (ZEND_TYPE_IS_INTERSECTION (type_list -> types [i ])) {
6357
+ zend_are_intersection_types_redundant (single_type , type_list -> types [i ]);
6358
+ continue ;
6359
+ }
6360
+ /* Type from type list is a simple type */
6361
+ zend_is_intersection_type_redundant_by_single_type (single_type , type_list -> types [i ]);
6362
+ }
6270
6363
continue ;
6271
6364
}
6272
6365
@@ -6304,17 +6397,7 @@ static zend_type zend_compile_typename(
6304
6397
type_list -> types [type_list -> num_types ++ ] = single_type ;
6305
6398
6306
6399
/* Check for trivially redundant class types */
6307
- for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6308
- if (ZEND_TYPE_IS_INTERSECTION (type_list -> types [i ])) {
6309
- continue ;
6310
- }
6311
- if (zend_string_equals_ci (
6312
- ZEND_TYPE_NAME (type_list -> types [i ]), ZEND_TYPE_NAME (single_type ))) {
6313
- zend_string * single_type_str = zend_type_to_string (single_type );
6314
- zend_error_noreturn (E_COMPILE_ERROR ,
6315
- "Duplicate type %s is redundant" , ZSTR_VAL (single_type_str ));
6316
- }
6317
- }
6400
+ zend_is_type_list_redundant_by_single_type (type_list , single_type );
6318
6401
}
6319
6402
}
6320
6403
}
@@ -6371,14 +6454,7 @@ static zend_type zend_compile_typename(
6371
6454
type_list -> types [type_list -> num_types ++ ] = single_type ;
6372
6455
6373
6456
/* Check for trivially redundant class types */
6374
- for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6375
- if (zend_string_equals_ci (
6376
- ZEND_TYPE_NAME (type_list -> types [i ]), ZEND_TYPE_NAME (single_type ))) {
6377
- zend_string * single_type_str = zend_type_to_string (single_type );
6378
- zend_error_noreturn (E_COMPILE_ERROR ,
6379
- "Duplicate type %s is redundant" , ZSTR_VAL (single_type_str ));
6380
- }
6381
- }
6457
+ zend_is_type_list_redundant_by_single_type (type_list , single_type );
6382
6458
}
6383
6459
6384
6460
ZEND_ASSERT (list -> children == type_list -> num_types );
0 commit comments