Skip to content

Commit 3444bd8

Browse files
committed
Use iterable instead of array|Traversable when usage of single type
1 parent e6b4472 commit 3444bd8

File tree

9 files changed

+26
-11
lines changed

9 files changed

+26
-11
lines changed

Zend/tests/type_declarations/intersection_types/variance/invalid5.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ class Test2 extends Test {
1515

1616
?>
1717
--EXPECTF--
18-
Fatal error: Declaration of Test2::method(): X&Y must be compatible with Test::method(): Traversable|array in %s on line %d
18+
Fatal error: Declaration of Test2::method(): X&Y must be compatible with Test::method(): iterable in %s on line %d

Zend/tests/type_declarations/iterable_001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@ object(ArrayIterator)#1 (1) {
4545
int(3)
4646
}
4747
}
48-
test(): Argument #1 ($iterable) must be of type Traversable|array, int given, called in %s on line %d
48+
test(): Argument #1 ($iterable) must be of type iterable, int given, called in %s on line %d

Zend/tests/type_declarations/iterable_002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ function baz(iterable $iterable = 1) {
1717

1818
?>
1919
--EXPECTF--
20-
Fatal error: Cannot use int as default value for parameter $iterable of type Traversable|array in %s on line %d
20+
Fatal error: Cannot use int as default value for parameter $iterable of type iterable in %s on line %d

Zend/tests/type_declarations/iterable_003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ array(0) {
2929
}
3030
object(Generator)#2 (0) {
3131
}
32-
baz(): Return value must be of type Traversable|array, int returned
32+
baz(): Return value must be of type iterable, int returned

Zend/tests/type_declarations/iterable_004.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ class Bar extends Foo {
2121

2222
?>
2323
--EXPECTF--
24-
Fatal error: Declaration of Bar::testScalar(Traversable|array $iterable) must be compatible with Foo::testScalar(int $int) in %s on line %d
24+
Fatal error: Declaration of Bar::testScalar(iterable $iterable) must be compatible with Foo::testScalar(int $int) in %s on line %d

Zend/tests/type_declarations/iterable_005.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ class TestScalar extends Test {
2929

3030
?>
3131
--EXPECTF--
32-
Fatal error: Declaration of TestScalar::method(): int must be compatible with Test::method(): Traversable|array in %s on line %d
32+
Fatal error: Declaration of TestScalar::method(): int must be compatible with Test::method(): iterable in %s on line %d

Zend/zend_compile.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,25 @@ static zend_string *resolve_class_name(zend_string *name, zend_class_entry *scop
11901190
zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scope) {
11911191
zend_string *str = NULL;
11921192

1193+
// TODO also handle case when iterable is in a union type?
1194+
// This would allow to remove the zend_type_to_string_ex() shim in Reflection
1195+
/* BC for iterable type */
1196+
if (UNEXPECTED(ZEND_TYPE_IS_ITERABLE_FALLBACK(type)) && ZEND_TYPE_HAS_NAME(type)) {
1197+
uint32_t type_mask = ZEND_TYPE_PURE_MASK(type);
1198+
if (type_mask != MAY_BE_ARRAY && type_mask != MAY_BE_ARRAY|MAY_BE_NULL) {
1199+
goto standard_resolve;
1200+
}
1201+
str = add_type_string(str, ZSTR_KNOWN(ZEND_STR_ITERABLE), /* is_intersection */ false);
1202+
1203+
if (type_mask == MAY_BE_NULL) {
1204+
zend_string *nullable_str = zend_string_concat2("?", 1, ZSTR_VAL(str), ZSTR_LEN(str));
1205+
zend_string_release(str);
1206+
return nullable_str;
1207+
}
1208+
return str;
1209+
}
1210+
1211+
standard_resolve:
11931212
if (ZEND_TYPE_HAS_LIST(type)) {
11941213
zend_type *list_type;
11951214
bool is_intersection = ZEND_TYPE_IS_INTERSECTION(type);

Zend/zend_execute.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,11 +1042,6 @@ static zend_always_inline bool zend_check_type_slow(
10421042
}
10431043

10441044
type_mask = ZEND_TYPE_FULL_MASK(*type);
1045-
/* Fallback for iterable */
1046-
// TODO Fix gen_stubs
1047-
if ((type_mask & _ZEND_TYPE_ITERABLE_BIT) && zend_is_iterable(arg)) {
1048-
return 1;
1049-
}
10501045
if ((type_mask & MAY_BE_CALLABLE) && zend_is_callable(arg, 0, NULL)) {
10511046
return 1;
10521047
}

Zend/zend_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ typedef struct {
144144
#define _ZEND_TYPE_NAME_BIT (1u << 24)
145145
#define _ZEND_TYPE_LIST_BIT (1u << 22)
146146
#define _ZEND_TYPE_KIND_MASK (_ZEND_TYPE_LIST_BIT|_ZEND_TYPE_NAME_BIT)
147+
/* For BC behaviour with iterable type */
147148
#define _ZEND_TYPE_ITERABLE_BIT (1u << 21)
148149
/* Whether the type list is arena allocated */
149150
#define _ZEND_TYPE_ARENA_BIT (1u << 20)

0 commit comments

Comments
 (0)