Skip to content

Commit 414f71a

Browse files
kocsismatemoliatabwoebiiluuu1994
authored
Typed class constants (#10444)
RFC: https://wiki.php.net/rfc/typed_class_constants Co-Authored-By: Ben <[email protected]> Co-Authored-By: Bob Weinand <[email protected]> Co-Authored-By: Ilija Tovilo <[email protected]>
1 parent 4dad419 commit 414f71a

File tree

53 files changed

+1227
-92
lines changed

Some content is hidden

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

53 files changed

+1227
-92
lines changed

UPGRADING

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ PHP 8.3 UPGRADE NOTES
5252
. Anonymous classes may now be marked as readonly.
5353
. Readonly properties can now be reinitialized during cloning.
5454
RFC: https://wiki.php.net/rfc/readonly_amendments
55+
. Class, interface, trait, and enum constants now support type
56+
declarations. RFC: https://wiki.php.net/rfc/typed_class_constants
5557

5658
- Posix
5759
. posix_getrlimit() now takes an optional $res parameter to allow fetching a
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Typed class constants (diamond error with self)
3+
--FILE--
4+
<?php
5+
class A {
6+
public const self CONST1 = C;
7+
}
8+
9+
try {
10+
define("C", new A());
11+
} catch (Error $exception) {
12+
echo $exception->getMessage() . "\n";
13+
}
14+
?>
15+
--EXPECT--
16+
Undefined constant "C"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Typed class constants (incompatible inheritance; simple)
3+
--FILE--
4+
<?php
5+
class A {
6+
public const int CONST1 = 1;
7+
}
8+
9+
class B extends A {
10+
public const string CONST1 = 'a';
11+
}
12+
?>
13+
--EXPECTF--
14+
Fatal error: Type of B::CONST1 must be compatible with A::CONST1 of type int in %s on line %d
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Typed class constants (incompatible inheritance; missing type in child)
3+
--FILE--
4+
<?php
5+
class A {
6+
public const int CONST1 = 1;
7+
}
8+
9+
class B extends A {
10+
public const CONST1 = 0;
11+
}
12+
?>
13+
--EXPECTF--
14+
Fatal error: Type of B::CONST1 must be compatible with A::CONST1 of type int in %s on line %d
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Typed class constants (incompatible composition; traits)
3+
--FILE--
4+
<?php
5+
6+
trait T {
7+
public const ?array CONST1 = [];
8+
}
9+
10+
class C {
11+
use T;
12+
13+
public const CONST1 = [];
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: C and T define the same constant (CONST1) in the composition of C. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Typed class constants (incompatible covariant composition; traits)
3+
--FILE--
4+
<?php
5+
6+
trait T {
7+
public const ?array CONST1 = [];
8+
}
9+
10+
class C {
11+
use T;
12+
13+
public const array CONST1 = [];
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: C and T define the same constant (CONST1) in the composition of C. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Typed class constants (incompatible contravariant composition; traits)
3+
--FILE--
4+
<?php
5+
6+
trait T {
7+
public const array CONST1 = [];
8+
}
9+
10+
class C {
11+
use T;
12+
13+
public const ?array CONST1 = [];
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: C and T define the same constant (CONST1) in the composition of C. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Typed class constants (inheritance success)
3+
--FILE--
4+
<?php
5+
class A {
6+
public const CONST1 = 1;
7+
public const CONST2 = 1;
8+
public const mixed CONST3 = 1;
9+
public const iterable CONST4 = [];
10+
}
11+
12+
class B extends A {
13+
public const int CONST1 = 0;
14+
public const mixed CONST2 = 0;
15+
public const mixed CONST3 = 0;
16+
public const array CONST4 = [];
17+
}
18+
19+
var_dump(B::CONST1);
20+
var_dump(B::CONST2);
21+
var_dump(B::CONST3);
22+
var_dump(B::CONST4);
23+
?>
24+
--EXPECT--
25+
int(0)
26+
int(0)
27+
int(0)
28+
array(0) {
29+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
Typed class constants (inheritance success - object types)
3+
--FILE--
4+
<?php
5+
class S implements Stringable {
6+
public function __toString() {
7+
return "";
8+
}
9+
}
10+
11+
class Z extends S {}
12+
13+
class A {
14+
public const object CONST1 = S;
15+
public const S CONST2 = S;
16+
public const S|Stringable CONST3 = S;
17+
public const S CONST4 = S;
18+
public const ?S CONST5 = S;
19+
}
20+
21+
class B extends A {
22+
public const S CONST1 = Z;
23+
public const Z CONST2 = Z;
24+
public const S CONST3 = Z;
25+
public const S&Stringable CONST4 = Z;
26+
public const (S&Stringable)|null CONST5 = Z;
27+
}
28+
29+
define("S", new S());
30+
define("Z", new Z());
31+
32+
var_dump(B::CONST1);
33+
var_dump(B::CONST2);
34+
var_dump(B::CONST3);
35+
var_dump(B::CONST4);
36+
var_dump(B::CONST5);
37+
?>
38+
--EXPECTF--
39+
object(Z)#%d (%d) {
40+
}
41+
object(Z)#%d (%d) {
42+
}
43+
object(Z)#%d (%d) {
44+
}
45+
object(Z)#%d (%d) {
46+
}
47+
object(Z)#%d (%d) {
48+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Typed class constants (inheritance; private constants)
3+
--FILE--
4+
<?php
5+
class A {
6+
private const int CONST1 = 1;
7+
}
8+
9+
class B extends A {
10+
public const string CONST1 = 'a';
11+
}
12+
13+
var_dump(B::CONST1);
14+
?>
15+
--EXPECT--
16+
string(1) "a"

0 commit comments

Comments
 (0)