Skip to content

Commit d5a51e6

Browse files
committed
Do not preserve BC for self/parent and always resolve when possible
1 parent 8635eea commit d5a51e6

File tree

41 files changed

+394
-779
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+394
-779
lines changed

Zend/tests/type_declarations/intersection_types/invalid_types/invalid_parent_type.phpt renamed to Zend/tests/type_declarations/intersection_types/invalid_types/invalid_unresolved_relative_type_parent.phpt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
--TEST--
2-
parent type cannot take part in an intersection type
2+
parent type cannot take part in an intersection type when unresolved
33
--FILE--
44
<?php
55

6-
class A {}
7-
8-
class B extends A {
6+
trait T {
97
public function foo(): parent&Iterator {}
108
}
119

Zend/tests/type_declarations/intersection_types/invalid_types/invalid_self_type.phpt renamed to Zend/tests/type_declarations/intersection_types/invalid_types/invalid_unresolved_relative_type_self.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
--TEST--
2-
self type cannot take part in an intersection type
2+
self type cannot take part in an intersection type when unresolved
33
--FILE--
44
<?php
55

6-
class A {
6+
trait T {
77
public function foo(): self&Iterator {}
88
}
99

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
parent type cannot take part in an intersection type
3+
--FILE--
4+
<?php
5+
6+
class A {}
7+
8+
class B extends A {
9+
public function foo(): parent&Iterator {}
10+
}
11+
12+
class C extends A {
13+
public function foo(): self&Iterator {}
14+
}
15+
16+
?>
17+
==DONE==
18+
--EXPECT--
19+
==DONE==

Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt

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

1313
?>
1414
--EXPECTF--
15-
Fatal error: Duplicate type parent is redundant in %s on line %d
15+
Fatal error: Duplicate type Foo is redundant in %s on line %d

Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ class Foo {
99

1010
?>
1111
--EXPECTF--
12-
Fatal error: Duplicate type self is redundant in %s on line %d
12+
Fatal error: Duplicate type Foo is redundant in %s on line %d

Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ class Foo {
99

1010
?>
1111
--EXPECTF--
12-
Fatal error: self resolves to Foo which is redundant in %s on line %d
12+
Fatal error: Duplicate type Foo is redundant in %s on line %d

Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ class Foo {
99

1010
?>
1111
--EXPECTF--
12-
Fatal error: self resolves to Foo which is redundant in %s on line %d
12+
Fatal error: Duplicate type Foo is redundant in %s on line %d

Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt

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

1313
?>
1414
--EXPECTF--
15-
Fatal error: parent resolves to Foo which is redundant in %s on line %d
15+
Fatal error: Duplicate type Foo is redundant in %s on line %d

Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt

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

1313
?>
1414
--EXPECTF--
15-
Fatal error: parent resolves to Foo which is redundant in %s on line %d
15+
Fatal error: Duplicate type Foo is redundant in %s on line %d

Zend/zend_compile.c

Lines changed: 11 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,8 +1354,6 @@ static zend_string *add_intersection_type(zend_string *str,
13541354
ZEND_TYPE_LIST_FOREACH(intersection_type_list, single_type) {
13551355
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*single_type));
13561356
ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*single_type));
1357-
ZEND_ASSERT(!ZEND_TYPE_IS_RELATIVE_SELF(*single_type) && "Compile time disallowed to have 'self' in intersection");
1358-
ZEND_ASSERT(!ZEND_TYPE_IS_RELATIVE_PARENT(*single_type) && "Compile time disallowed to have 'parent' in intersection");
13591357

13601358
intersection_str = add_type_string(intersection_str, ZEND_TYPE_NAME(*single_type), /* is_intersection */ true);
13611359
} ZEND_TYPE_LIST_FOREACH_END();
@@ -1390,29 +1388,13 @@ zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scop
13901388
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type));
13911389
ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*list_type));
13921390

1393-
/* We already have resolved types from compile time
1394-
* Mimic unresolved types for BC with "self" and "parent" */
1395-
if (!scope && ZEND_TYPE_IS_RELATIVE_SELF(*list_type)) {
1396-
str = add_type_string(str, ZSTR_KNOWN(ZEND_STR_SELF), /* is_intersection */ false);
1397-
} else if (!scope && ZEND_TYPE_IS_RELATIVE_PARENT(*list_type)) {
1398-
str = add_type_string(str, ZSTR_KNOWN(ZEND_STR_PARENT), /* is_intersection */ false);
1399-
} else {
1400-
zend_string *name = ZEND_TYPE_NAME(*list_type);
1401-
zend_string *resolved = resolve_class_name(name, scope);
1402-
str = add_type_string(str, resolved, /* is_intersection */ false);
1403-
zend_string_release(resolved);
1404-
}
1391+
zend_string *name = ZEND_TYPE_NAME(*list_type);
1392+
zend_string *resolved = resolve_class_name(name, scope);
1393+
str = add_type_string(str, resolved, /* is_intersection */ false);
1394+
zend_string_release(resolved);
14051395
} ZEND_TYPE_LIST_FOREACH_END();
14061396
} else if (ZEND_TYPE_HAS_NAME(type)) {
1407-
/* We already have resolved types from compile time
1408-
* Mimic unresolved types for BC with "self" and "parent" */
1409-
if (!scope && ZEND_TYPE_IS_RELATIVE_SELF(type)) {
1410-
str = ZSTR_KNOWN(ZEND_STR_SELF);
1411-
} else if (!scope && ZEND_TYPE_IS_RELATIVE_PARENT(type)) {
1412-
str = ZSTR_KNOWN(ZEND_STR_PARENT);
1413-
} else {
1414-
str = resolve_class_name(ZEND_TYPE_NAME(type), scope);
1415-
}
1397+
str = resolve_class_name(ZEND_TYPE_NAME(type), scope);
14161398
}
14171399

14181400
uint32_t type_mask = ZEND_TYPE_PURE_MASK(type);
@@ -6631,7 +6613,6 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
66316613
} else {
66326614
const char *correct_name;
66336615
uint32_t fetch_type = zend_get_class_fetch_type_ast(ast);
6634-
uint32_t type_flags = 0;
66356616
zend_string *class_name = type_name;
66366617

66376618
if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
@@ -6642,15 +6623,13 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
66426623

66436624
zend_ensure_valid_class_fetch_type(fetch_type);
66446625
if (fetch_type == ZEND_FETCH_CLASS_SELF) {
6645-
type_flags = _ZEND_TYPE_SELF_BIT;
66466626
/* Scope might be unknown for unbound closures and traits */
66476627
if (zend_is_scope_known()) {
66486628
class_name = CG(active_class_entry)->name;
66496629
ZEND_ASSERT(class_name && "must know class name when resolving self type at compile time");
66506630
}
66516631
} else {
66526632
ZEND_ASSERT(fetch_type == ZEND_FETCH_CLASS_PARENT);
6653-
type_flags = _ZEND_TYPE_PARENT_BIT;
66546633
/* Scope might be unknown for unbound closures and traits */
66556634
if (zend_is_scope_known()) {
66566635
class_name = CG(active_class_entry)->parent_name;
@@ -6681,7 +6660,7 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
66816660

66826661
class_name = zend_new_interned_string(class_name);
66836662
zend_alloc_ce_cache(class_name);
6684-
return (zend_type) ZEND_TYPE_INIT_CLASS(class_name, /* allow null */ false, type_flags);
6663+
return (zend_type) ZEND_TYPE_INIT_CLASS(class_name, /* allow null */ false, 0);
66856664
}
66866665
}
66876666
}
@@ -6763,28 +6742,7 @@ static void zend_is_type_list_redundant_by_single_type(zend_type_list *type_list
67636742
}
67646743
if (zend_string_equals_ci(ZEND_TYPE_NAME(type_list->types[i]), ZEND_TYPE_NAME(type))) {
67656744
zend_string *single_type_str = zend_type_to_string(type);
6766-
if (ZEND_TYPE_IS_RELATIVE_TYPE(type)) {
6767-
if ( (
6768-
ZEND_TYPE_FULL_MASK(type)
6769-
& ZEND_TYPE_FULL_MASK(type_list->types[i])
6770-
& (_ZEND_TYPE_RELATIVE_TYPE_MASK)) != 0
6771-
) {
6772-
zend_error_noreturn(E_COMPILE_ERROR, "Duplicate type %s is redundant", ZSTR_VAL(single_type_str));
6773-
}
6774-
/* zend_type_to_string() will return "self" or "parent" where the resolved type is stored in
6775-
* ZEND_TYPE_NAME() */
6776-
zend_error_noreturn(E_COMPILE_ERROR, "%s resolves to %s which is redundant",
6777-
ZSTR_VAL(single_type_str), ZSTR_VAL(ZEND_TYPE_NAME(type))
6778-
);
6779-
} else if (ZEND_TYPE_IS_RELATIVE_TYPE(type_list->types[i])) {
6780-
/* zend_type_to_string() will return "self" or "parent" where the resolved type is stored in
6781-
* ZEND_TYPE_NAME() */
6782-
zend_error_noreturn(E_COMPILE_ERROR, "%s resolves to %s which is redundant",
6783-
ZEND_TYPE_IS_RELATIVE_SELF(type_list->types[i]) ? "self" : "parent", ZSTR_VAL(ZEND_TYPE_NAME(type))
6784-
);
6785-
} else {
6786-
zend_error_noreturn(E_COMPILE_ERROR, "Duplicate type %s is redundant", ZSTR_VAL(single_type_str));
6787-
}
6745+
zend_error_noreturn(E_COMPILE_ERROR, "Duplicate type %s is redundant", ZSTR_VAL(single_type_str));
67886746
}
67896747
}
67906748
}
@@ -6880,8 +6838,6 @@ static zend_type zend_compile_typename_ex(
68806838
/* The first class type can be stored directly as the type ptr payload. */
68816839
ZEND_TYPE_SET_PTR(type, ZEND_TYPE_NAME(single_type));
68826840
ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_NAME_BIT;
6883-
/* Add flags indicating the named type is self/parent */
6884-
ZEND_TYPE_FULL_MASK(type) |= (ZEND_TYPE_FULL_MASK(single_type) & _ZEND_TYPE_RELATIVE_TYPE_MASK);
68856841
} else {
68866842
if (type_list->num_types == 0) {
68876843
/* Switch from single name to name list. */
@@ -6890,8 +6846,6 @@ static zend_type zend_compile_typename_ex(
68906846
/* Clear MAY_BE_* type flags */
68916847
ZEND_TYPE_FULL_MASK(type_list->types[0]) &= ~_ZEND_TYPE_MAY_BE_MASK;
68926848
ZEND_TYPE_SET_LIST(type, type_list);
6893-
/* Clear flags indicating the named type is self/parent */
6894-
ZEND_TYPE_FULL_MASK(type) &= ~_ZEND_TYPE_RELATIVE_TYPE_MASK;
68956849
}
68966850

68976851
type_list->types[type_list->num_types++] = single_type;
@@ -6953,11 +6907,10 @@ static zend_type zend_compile_typename_ex(
69536907
zend_string_release_ex(standard_type_str, false);
69546908
}
69556909
/* Check for "self" and "parent" too */
6956-
if (ZEND_TYPE_IS_RELATIVE_SELF(single_type)) {
6957-
zend_error_noreturn(E_COMPILE_ERROR, "Type self cannot be part of an intersection type");
6958-
}
6959-
if (ZEND_TYPE_IS_RELATIVE_PARENT(single_type)) {
6960-
zend_error_noreturn(E_COMPILE_ERROR, "Type parent cannot be part of an intersection type");
6910+
if (zend_string_equals_literal_ci(ZEND_TYPE_NAME(single_type), "self")
6911+
|| zend_string_equals_literal_ci(ZEND_TYPE_NAME(single_type), "parent")) {
6912+
zend_error_noreturn(E_COMPILE_ERROR,
6913+
"Type %s cannot be part of an intersection type", ZSTR_VAL(ZEND_TYPE_NAME(single_type)));
69616914
}
69626915

69636916
/* Add type to the type list */

0 commit comments

Comments
 (0)