@@ -512,10 +512,13 @@ static zend_generic_parameter_list *zend_compile_generic_type_parameter_list(zen
512512 zend_generic_parameter_list * params =
513513 zend_generic_parameter_list_alloc (list -> children , /* persistent */ false);
514514
515+ zend_string * prev_optional_name = NULL ;
516+
515517 for (uint32_t i = 0 ; i < list -> children ; i ++ ) {
516518 zend_ast * param_ast = list -> child [i ];
517519 ZEND_ASSERT (param_ast -> kind == ZEND_AST_GENERIC_TYPE_PARAMETER );
518520 zend_string * name = zval_make_interned_string (zend_ast_get_zval (param_ast -> child [0 ]));
521+ bool has_default = param_ast -> child [2 ] != NULL ;
519522
520523 for (uint32_t j = 0 ; j < i ; j ++ ) {
521524 if (zend_string_equals (params -> parameters [j ].name , name )) {
@@ -533,6 +536,19 @@ static zend_generic_parameter_list *zend_compile_generic_type_parameter_list(zen
533536 "Type parameter %s shadows enclosing type parameter" , ZSTR_VAL (dup ));
534537 }
535538
539+ if (!has_default && prev_optional_name != NULL ) {
540+ zend_string * cur = zend_string_copy (name );
541+ zend_string * prev = zend_string_copy (prev_optional_name );
542+ zend_generic_parameter_list_destroy (params );
543+ zend_error_noreturn (E_COMPILE_ERROR ,
544+ "Optional type parameter %s cannot be declared before required type parameter %s" ,
545+ ZSTR_VAL (prev ), ZSTR_VAL (cur ));
546+ }
547+
548+ if (has_default && prev_optional_name == NULL ) {
549+ prev_optional_name = name ;
550+ }
551+
536552 params -> parameters [i ].name = zend_string_copy (name );
537553 params -> parameters [i ].variance = (uint8_t ) param_ast -> attr ;
538554 }
0 commit comments