Skip to content

Commit 0cfa2e5

Browse files
committed
Merge branch 'PHP-7.4' of git://github.com/php/php-src into PHP-7.4
2 parents 69190ce + fc9d452 commit 0cfa2e5

Some content is hidden

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

43 files changed

+1838
-1329
lines changed

UPGRADING

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,9 @@ PHP 7.4 UPGRADE NOTES
163163
public function method(): B {}
164164
}
165165

166-
This feature is currently restricted to non-cyclic type references only.
166+
Full variance support is only available if autoloading is used. Inside a
167+
single file only non-cyclic type references are possible, because all
168+
classes need to be available before they are referenced.
167169
RFC: https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
168170

169171
. Added support for coalesce assign (??=) operator. For example:

Zend/tests/bug30922.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ var_dump($a instanceOf A);
1010
echo "ok\n";
1111
?>
1212
--EXPECTF--
13-
Fatal error: Interface 'RecurisiveFooFar' not found in %sbug30922.php on line %d
13+
Fatal error: Interface RecurisiveFooFar cannot implement itself in %s on line %d
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
Class order allowed with autoloading (1)
3+
--FILE--
4+
<?php
5+
6+
spl_autoload_register(function($class) {
7+
if ($class === 'A') {
8+
class A {
9+
public function method() : B {}
10+
}
11+
var_dump(new A);
12+
} else if ($class == 'B') {
13+
class B extends A {
14+
public function method() : C {}
15+
}
16+
var_dump(new B);
17+
} else {
18+
class C extends B {
19+
}
20+
var_dump(new C);
21+
}
22+
});
23+
24+
var_dump(new C);
25+
26+
?>
27+
===DONE===
28+
--EXPECT--
29+
object(A)#2 (0) {
30+
}
31+
object(B)#2 (0) {
32+
}
33+
object(C)#2 (0) {
34+
}
35+
object(C)#2 (0) {
36+
}
37+
===DONE===
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Class order allowed with autoloading (2)
3+
--FILE--
4+
<?php
5+
6+
spl_autoload_register(function($class) {
7+
if ($class === 'A') {
8+
class A {
9+
public function method() : B {}
10+
}
11+
var_dump(new A);
12+
} else if ($class == 'B') {
13+
class B extends A {
14+
public function method() : C {}
15+
}
16+
var_dump(new B);
17+
} else {
18+
class C extends B {
19+
}
20+
var_dump(new C);
21+
}
22+
});
23+
24+
// Same as autoload1 test case, but with a different autoloading root
25+
var_dump(new B);
26+
27+
?>
28+
===DONE===
29+
--EXPECT--
30+
object(A)#2 (0) {
31+
}
32+
object(C)#2 (0) {
33+
}
34+
object(B)#2 (0) {
35+
}
36+
object(B)#2 (0) {
37+
}
38+
===DONE===
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
Class order allowed with autoloading (3)
3+
--FILE--
4+
<?php
5+
6+
spl_autoload_register(function($class) {
7+
if ($class == 'A') {
8+
class A {
9+
public function method(): X {}
10+
}
11+
var_dump(new A);
12+
} else if ($class == 'B') {
13+
class B extends A {
14+
public function method(): Y {}
15+
}
16+
var_dump(new B);
17+
} else if ($class == 'X') {
18+
class X {
19+
public function method(): A {}
20+
}
21+
var_dump(new X);
22+
} else if ($class == 'Y') {
23+
class Y extends X {
24+
public function method(): B {}
25+
}
26+
var_dump(new Y);
27+
}
28+
});
29+
30+
var_dump(new B);
31+
32+
?>
33+
===DONE===
34+
--EXPECT--
35+
object(A)#2 (0) {
36+
}
37+
object(X)#2 (0) {
38+
}
39+
object(Y)#2 (0) {
40+
}
41+
object(B)#2 (0) {
42+
}
43+
object(B)#2 (0) {
44+
}
45+
===DONE===
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
Class order allowed with autoloading (4)
3+
--FILE--
4+
<?php
5+
6+
// Same as autoload3 test case, but with X, Y being interfaces.
7+
spl_autoload_register(function($class) {
8+
if ($class == 'A') {
9+
class A {
10+
public function method(): X {}
11+
}
12+
var_dump(new A);
13+
} else if ($class == 'B') {
14+
class B extends A {
15+
public function method(): Y {}
16+
}
17+
var_dump(new B);
18+
} else if ($class == 'X') {
19+
interface X {
20+
public function method(): A;
21+
}
22+
var_dump(interface_exists('X'));
23+
} else if ($class == 'Y') {
24+
interface Y extends X {
25+
public function method(): B;
26+
}
27+
var_dump(interface_exists('Y'));
28+
}
29+
});
30+
31+
var_dump(new B);
32+
33+
?>
34+
===DONE===
35+
--EXPECT--
36+
object(A)#2 (0) {
37+
}
38+
bool(true)
39+
bool(true)
40+
object(B)#2 (0) {
41+
}
42+
object(B)#2 (0) {
43+
}
44+
===DONE===
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
Class order allowed with autoloading (5)
3+
--FILE--
4+
<?php
5+
6+
// Similar to variance3, but one more class hierarchy in the cycle
7+
spl_autoload_register(function($class) {
8+
if ($class == 'A') {
9+
class A {
10+
public function method(): X {}
11+
}
12+
var_dump(new A);
13+
} else if ($class == 'B') {
14+
class B extends A {
15+
public function method(): Y {}
16+
}
17+
var_dump(new B);
18+
} else if ($class == 'X') {
19+
class X {
20+
public function method(): Q {}
21+
}
22+
var_dump(new X);
23+
} else if ($class == 'Y') {
24+
class Y extends X {
25+
public function method(): R {}
26+
}
27+
var_dump(new Y);
28+
} else if ($class == 'Q') {
29+
class Q {
30+
public function method(): A {}
31+
}
32+
var_dump(new Q);
33+
} else if ($class == 'R') {
34+
class R extends Q {
35+
public function method(): B {}
36+
}
37+
var_dump(new R);
38+
}
39+
});
40+
41+
var_dump(new B);
42+
43+
?>
44+
===DONE===
45+
--EXPECT--
46+
object(A)#2 (0) {
47+
}
48+
object(X)#2 (0) {
49+
}
50+
object(Q)#2 (0) {
51+
}
52+
object(R)#2 (0) {
53+
}
54+
object(Y)#2 (0) {
55+
}
56+
object(B)#2 (0) {
57+
}
58+
object(B)#2 (0) {
59+
}
60+
===DONE===
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
--TEST--
2-
Returns are covariant, but we don't allow the code due to class ordering (autoload variation)
2+
Variance error in the presence of autoloading (1)
33
--FILE--
44
<?php
55

66
spl_autoload_register(function($class) {
77
if ($class === 'A') {
88
class A {
9-
public function method() : B {}
9+
public function method() : C {}
1010
}
1111
} else if ($class == 'B') {
1212
class B extends A {
13-
public function method() : C {}
13+
public function method() : B {}
1414
}
1515
} else {
1616
class C extends B {
1717
}
1818
}
1919
});
2020

21-
$c = new C;
21+
$b = new B;
2222

2323
?>
2424
--EXPECTF--
25-
Fatal error: Could not check compatibility between B::method(): C and A::method(): B, because class C is not available in %s on line %d
25+
Fatal error: Declaration of B::method(): B must be compatible with A::method(): C in %s on line %d
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Variance error in the presence of autoloading (2)
3+
--FILE--
4+
<?php
5+
6+
// Same as autoload_error1, but for argument types.
7+
spl_autoload_register(function($class) {
8+
if ($class === 'A') {
9+
class A {
10+
public function method(B $x) {}
11+
}
12+
} else if ($class == 'B') {
13+
class B extends A {
14+
public function method(C $x) {}
15+
}
16+
} else {
17+
class C extends B {
18+
}
19+
}
20+
});
21+
22+
$b = new B;
23+
$c = new C;
24+
25+
?>
26+
--EXPECTF--
27+
Warning: Declaration of B::method(C $x) should be compatible with A::method(B $x) in %s on line %d
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Variance error in the presence of autoloading (3)
3+
--FILE--
4+
<?php
5+
6+
spl_autoload_register(function($class) {
7+
if ($class == 'A') {
8+
class A {
9+
public function method(): X {}
10+
}
11+
} else if ($class == 'B') {
12+
class B extends A {
13+
public function method(): Y {}
14+
}
15+
} else if ($class == 'X') {
16+
class X {
17+
public function method(): Q {}
18+
}
19+
} else if ($class == 'Y') {
20+
class Y extends X {
21+
public function method(): R {}
22+
}
23+
} else if ($class == 'Q') {
24+
class Q {
25+
public function method(): B {}
26+
}
27+
} else if ($class == 'R') {
28+
class R extends Q {
29+
public function method(): A {}
30+
}
31+
}
32+
});
33+
34+
$b = new B;
35+
36+
?>
37+
--EXPECTF--
38+
Fatal error: Declaration of R::method(): A must be compatible with Q::method(): B in %s on line %d
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
Variance error in the presence of autoloading (4)
3+
--FILE--
4+
<?php
5+
6+
spl_autoload_register(function($class) {
7+
if ($class == 'A') {
8+
class A {
9+
public function method(): X {}
10+
}
11+
var_dump(new A);
12+
} else if ($class == 'B') {
13+
class B extends A {
14+
public function method(): Y {}
15+
}
16+
var_dump(new B);
17+
} else if ($class == 'X') {
18+
class X {
19+
public function method(): B {}
20+
}
21+
var_dump(new X);
22+
} else if ($class == 'Y') {
23+
class Y extends X {
24+
public function method(): A {}
25+
}
26+
var_dump(new Y);
27+
}
28+
});
29+
30+
var_dump(new B);
31+
32+
?>
33+
--EXPECTF--
34+
object(A)#2 (0) {
35+
}
36+
object(X)#2 (0) {
37+
}
38+
39+
Fatal error: Declaration of Y::method(): A must be compatible with X::method(): B in %s on line %d

0 commit comments

Comments
 (0)