@@ -6218,6 +6218,91 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
6218
6218
}
6219
6219
}
6220
6220
6221
+ static void zend_are_intersection_types_redundant (zend_type left_type , zend_type right_type )
6222
+ {
6223
+ ZEND_ASSERT (ZEND_TYPE_IS_INTERSECTION (left_type ));
6224
+ ZEND_ASSERT (ZEND_TYPE_IS_INTERSECTION (right_type ));
6225
+ zend_type_list * l_type_list = ZEND_TYPE_LIST (left_type );
6226
+ zend_type_list * r_type_list = ZEND_TYPE_LIST (right_type );
6227
+ zend_type_list * smaller_type_list , * larger_type_list ;
6228
+ bool flipped = false;
6229
+
6230
+ if (r_type_list -> num_types < l_type_list -> num_types ) {
6231
+ smaller_type_list = r_type_list ;
6232
+ larger_type_list = l_type_list ;
6233
+ flipped = true;
6234
+ } else {
6235
+ smaller_type_list = l_type_list ;
6236
+ larger_type_list = r_type_list ;
6237
+ }
6238
+
6239
+ int sum = 0 ;
6240
+ zend_type * outer_type ;
6241
+ ZEND_TYPE_LIST_FOREACH (smaller_type_list , outer_type )
6242
+ zend_type * inner_type ;
6243
+ ZEND_TYPE_LIST_FOREACH (larger_type_list , inner_type )
6244
+ if (zend_string_equals_ci (ZEND_TYPE_NAME (* inner_type ), ZEND_TYPE_NAME (* outer_type ))) {
6245
+ sum ++ ;
6246
+ break ;
6247
+ }
6248
+ ZEND_TYPE_LIST_FOREACH_END ();
6249
+ ZEND_TYPE_LIST_FOREACH_END ();
6250
+
6251
+ if (sum == smaller_type_list -> num_types ) {
6252
+ zend_string * l_type_str = zend_type_to_string (left_type );
6253
+ zend_string * r_type_str = zend_type_to_string (right_type );
6254
+ if (smaller_type_list -> num_types == larger_type_list -> num_types ) {
6255
+ if (flipped ) {
6256
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is redundant with type %s" ,
6257
+ ZSTR_VAL (r_type_str ), ZSTR_VAL (l_type_str ));
6258
+ } else {
6259
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is redundant with type %s" ,
6260
+ ZSTR_VAL (l_type_str ), ZSTR_VAL (r_type_str ));
6261
+ }
6262
+ } else {
6263
+ if (flipped ) {
6264
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is less restrictive than 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 less restrictive than type %s" ,
6268
+ ZSTR_VAL (l_type_str ), ZSTR_VAL (r_type_str ));
6269
+ }
6270
+ }
6271
+ }
6272
+ }
6273
+
6274
+ static void zend_is_intersection_type_redundant_by_single_type (zend_type intersection_type , zend_type single_type )
6275
+ {
6276
+ ZEND_ASSERT (ZEND_TYPE_IS_INTERSECTION (intersection_type ));
6277
+ ZEND_ASSERT (!ZEND_TYPE_IS_INTERSECTION (single_type ));
6278
+
6279
+ zend_type * single_intersection_type = NULL ;
6280
+ ZEND_TYPE_FOREACH (intersection_type , single_intersection_type )
6281
+ if (zend_string_equals_ci (ZEND_TYPE_NAME (* single_intersection_type ), ZEND_TYPE_NAME (single_type ))) {
6282
+ zend_string * single_type_str = zend_type_to_string (single_type );
6283
+ zend_string * complete_type = zend_type_to_string (intersection_type );
6284
+ zend_error_noreturn (E_COMPILE_ERROR , "Type %s is less restrictive than type %s" ,
6285
+ ZSTR_VAL (single_type_str ), ZSTR_VAL (complete_type ));
6286
+ }
6287
+ ZEND_TYPE_FOREACH_END ();
6288
+ }
6289
+
6290
+ /* Used by both intersection and union types prior to transforming the type list to a full zend_type */
6291
+ static void zend_is_type_list_redundant_by_single_type (zend_type_list * type_list , zend_type type )
6292
+ {
6293
+ ZEND_ASSERT (!ZEND_TYPE_IS_INTERSECTION (type ));
6294
+ for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6295
+ if (ZEND_TYPE_IS_INTERSECTION (type_list -> types [i ])) {
6296
+ zend_is_intersection_type_redundant_by_single_type (type_list -> types [i ], type );
6297
+ continue ;
6298
+ }
6299
+ if (zend_string_equals_ci (ZEND_TYPE_NAME (type_list -> types [i ]), ZEND_TYPE_NAME (type ))) {
6300
+ zend_string * single_type_str = zend_type_to_string (type );
6301
+ zend_error_noreturn (E_COMPILE_ERROR , "Duplicate type %s is redundant" , ZSTR_VAL (single_type_str ));
6302
+ }
6303
+ }
6304
+ }
6305
+
6221
6306
static zend_type zend_compile_typename (
6222
6307
zend_ast * ast , bool force_allow_null ) /* {{{ */
6223
6308
{
@@ -6258,7 +6343,15 @@ static zend_type zend_compile_typename(
6258
6343
6259
6344
type_list -> types [type_list -> num_types ++ ] = single_type ;
6260
6345
6261
- /* TODO Check for trivially redundant class types? */
6346
+ /* Check for trivially redundant class types */
6347
+ for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6348
+ if (ZEND_TYPE_IS_INTERSECTION (type_list -> types [i ])) {
6349
+ zend_are_intersection_types_redundant (single_type , type_list -> types [i ]);
6350
+ continue ;
6351
+ }
6352
+ /* Type from type list is a simple type */
6353
+ zend_is_intersection_type_redundant_by_single_type (single_type , type_list -> types [i ]);
6354
+ }
6262
6355
continue ;
6263
6356
}
6264
6357
@@ -6296,17 +6389,7 @@ static zend_type zend_compile_typename(
6296
6389
type_list -> types [type_list -> num_types ++ ] = single_type ;
6297
6390
6298
6391
/* Check for trivially redundant class types */
6299
- for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6300
- if (ZEND_TYPE_IS_INTERSECTION (type_list -> types [i ])) {
6301
- continue ;
6302
- }
6303
- if (zend_string_equals_ci (
6304
- ZEND_TYPE_NAME (type_list -> types [i ]), ZEND_TYPE_NAME (single_type ))) {
6305
- zend_string * single_type_str = zend_type_to_string (single_type );
6306
- zend_error_noreturn (E_COMPILE_ERROR ,
6307
- "Duplicate type %s is redundant" , ZSTR_VAL (single_type_str ));
6308
- }
6309
- }
6392
+ zend_is_type_list_redundant_by_single_type (type_list , single_type );
6310
6393
}
6311
6394
}
6312
6395
}
@@ -6359,14 +6442,7 @@ static zend_type zend_compile_typename(
6359
6442
type_list -> types [type_list -> num_types ++ ] = single_type ;
6360
6443
6361
6444
/* Check for trivially redundant class types */
6362
- for (size_t i = 0 ; i < type_list -> num_types - 1 ; i ++ ) {
6363
- if (zend_string_equals_ci (
6364
- ZEND_TYPE_NAME (type_list -> types [i ]), ZEND_TYPE_NAME (single_type ))) {
6365
- zend_string * single_type_str = zend_type_to_string (single_type );
6366
- zend_error_noreturn (E_COMPILE_ERROR ,
6367
- "Duplicate type %s is redundant" , ZSTR_VAL (single_type_str ));
6368
- }
6369
- }
6445
+ zend_is_type_list_redundant_by_single_type (type_list , single_type );
6370
6446
}
6371
6447
6372
6448
ZEND_ASSERT (list -> children == type_list -> num_types );
0 commit comments