Skip to content

Commit 336ca09

Browse files
committed
Added mixed argument type & return type
1 parent fc336c7 commit 336ca09

File tree

7 files changed

+72
-1
lines changed

7 files changed

+72
-1
lines changed

Zend/tests/typehints/mixed.phpt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
Test various types passed to mixed type.
3+
--FILE--
4+
<?php
5+
6+
$types = [
7+
NULL,
8+
TRUE,
9+
123,
10+
123.456,
11+
'php',
12+
new stdClass,
13+
fopen(__FILE__, 'r'),
14+
];
15+
16+
function test(mixed $arg) {
17+
var_dump($arg);
18+
}
19+
20+
foreach ($types as $type) {
21+
test($type);
22+
}
23+
--EXPECTF--
24+
NULL
25+
bool(true)
26+
int(123)
27+
float(123.456)
28+
string(3) "php"
29+
object(stdClass)#%d (%d) {
30+
}
31+
resource(%d) of type (stream)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Test mixed variance in inheritance.
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
function test(mixed $arg): mixed
8+
{
9+
return $arg;
10+
}
11+
}
12+
13+
class Bar extends Foo {
14+
function test($arg) {
15+
return parent::test($arg);
16+
}
17+
}
18+
19+
class Baz extends bar {
20+
function test(mixed $arg): mixed {
21+
return parent::test($arg);
22+
}
23+
}
24+
25+
var_dump((new Baz())->test(123));
26+
--EXPECT--
27+
int(123)

Zend/zend_API.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ ZEND_API char *zend_get_type_by_const(int type) /* {{{ */
189189
return "array";
190190
case IS_VOID:
191191
return "void";
192+
case IS_MIXED:
193+
return "mixed";
192194
default:
193195
return "unknown";
194196
}

Zend/zend_compile.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ static const struct reserved_class_name reserved_class_names[] = {
163163
{ZEND_STRL("void")},
164164
{ZEND_STRL("iterable")},
165165
{ZEND_STRL("object")},
166+
{ZEND_STRL("mixed")},
166167
{NULL, 0}
167168
};
168169

@@ -209,6 +210,7 @@ static const builtin_type_info builtin_types[] = {
209210
{ZEND_STRL("void"), IS_VOID},
210211
{ZEND_STRL("iterable"), IS_ITERABLE},
211212
{ZEND_STRL("object"), IS_OBJECT},
213+
{ZEND_STRL("mixed"), IS_MIXED},
212214
{NULL, 0, IS_UNDEF}
213215
};
214216

Zend/zend_execute.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,8 @@ static zend_always_inline zend_bool zend_check_type(
859859
} else if (ZEND_TYPE_CODE(type) == _IS_BOOL &&
860860
EXPECTED(Z_TYPE_P(arg) == IS_FALSE || Z_TYPE_P(arg) == IS_TRUE)) {
861861
return 1;
862+
} else if (ZEND_TYPE_CODE(type) == IS_MIXED) {
863+
return 1;
862864
} else {
863865
return zend_verify_scalar_type_hint(ZEND_TYPE_CODE(type), arg,
864866
is_return_type ? ZEND_RET_USES_STRICT_TYPES() : ZEND_ARG_USES_STRICT_TYPES());

Zend/zend_inheritance.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,10 @@ static int zend_do_perform_arg_type_hint_check(const zend_function *fe, zend_arg
253253
}
254254

255255
if (!ZEND_TYPE_IS_SET(proto_arg_info->type)) {
256-
/* Child defines a type, but parent doesn't, violates LSP */
256+
/* Child defines a type, but parent doesn't, violates LSP, unless it's a mixed type */
257+
if (ZEND_TYPE_CODE(fe_arg_info->type) == IS_MIXED) {
258+
return 1;
259+
}
257260
return 0;
258261
}
259262

@@ -359,6 +362,9 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
359362
if (proto->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
360363
/* Removing a return type is not valid. */
361364
if (!(fe->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
365+
if (ZEND_TYPE_CODE(proto->common.arg_info[-1].type) == IS_MIXED) {
366+
return 1;
367+
}
362368
return 0;
363369
}
364370

Zend/zend_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ struct _zend_ast_ref {
379379
#define _IS_BOOL 13
380380
#define IS_CALLABLE 14
381381
#define IS_ITERABLE 19
382+
#define IS_MIXED 21
382383
#define IS_VOID 18
383384

384385
/* internal types */

0 commit comments

Comments
 (0)