-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Support never types #6761
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Support never types #6761
Changes from 18 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
d5d2d03
Support noreturn types
muglug d24d458
Add more tests
muglug a763287
Attempt opcode adjustment
muglug 4dd3c32
Add covariance checks
muglug db5b67c
Fix test formatting
muglug 0395486
Do straightforward noreturn comparison
muglug f59b56a
Do straightforward noreturn comparison
muglug 03a9ede
Fix test description
muglug 984de02
Make exception more precise
muglug 3ec058f
Don’t emit return type check if noreturn is given
muglug 38449b7
Add a reflection test
muglug e3033ae
Incorporate opcache suggestions from @iluuu1994
muglug 56ae52e
Add combinations of return and throw as tests
muglug 6d3a76d
Add specific return-by-ref test and remove unnecessary check
muglug 1e7ce1f
Add another test for noreturn as the bottom type
muglug 8763f7f
Add a test for __toString noreturn
muglug 30f2013
Merge remote-tracking branch 'upstream/master' into support-noreturn
muglug 1c05283
Use never instead of noreturn
muglug fd5bfa3
Migrate more to never
muglug 47af885
Update message for never-returning function
muglug b087460
Fix spacing
muglug f59ec6d
Improve some language and other PR changes
muglug f16cb38
Merge remote-tracking branch 'upstream/master' into support-noreturn
muglug 1b68ae6
Add return type for generator returning never
muglug 0def0c9
Simplify zend_verify_never_error
muglug 044207b
Release memory
muglug File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
--TEST-- | ||
never return type: acceptable cases | ||
--FILE-- | ||
<?php | ||
|
||
function foo(): never { | ||
throw new Exception('bad'); | ||
} | ||
|
||
try { | ||
foo(); | ||
} catch (Exception $e) { | ||
// do nothing | ||
} | ||
|
||
function calls_foo(): never { | ||
foo(); | ||
} | ||
|
||
try { | ||
calls_foo(); | ||
} catch (Exception $e) { | ||
// do nothing | ||
} | ||
|
||
echo "OK!", PHP_EOL; | ||
?> | ||
--EXPECT-- | ||
OK! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
--TEST-- | ||
never return type: acceptable covariance cases | ||
--FILE-- | ||
<?php | ||
|
||
class A | ||
{ | ||
public function foo(): string | ||
{ | ||
return "hello"; | ||
} | ||
|
||
public function bar(): never | ||
{ | ||
throw new UnexpectedValueException('parent'); | ||
} | ||
|
||
public function &baz() | ||
{ | ||
} | ||
|
||
public function someReturningStaticMethod() : static | ||
{ | ||
} | ||
} | ||
|
||
class B extends A | ||
{ | ||
public function foo(): never | ||
{ | ||
throw new UnexpectedValueException('bad'); | ||
} | ||
|
||
public function bar(): never | ||
{ | ||
throw new UnexpectedValueException('child'); | ||
} | ||
|
||
public function &baz(): never | ||
{ | ||
throw new UnexpectedValueException('child'); | ||
} | ||
|
||
public function someReturningStaticMethod(): never | ||
{ | ||
throw new UnexpectedValueException('child'); | ||
} | ||
} | ||
|
||
try { | ||
(new B)->foo(); | ||
} catch (UnexpectedValueException $e) { | ||
// do nothing | ||
} | ||
|
||
try { | ||
(new B)->bar(); | ||
} catch (UnexpectedValueException $e) { | ||
// do nothing | ||
} | ||
|
||
try { | ||
(new B)->baz(); | ||
} catch (UnexpectedValueException $e) { | ||
// do nothing | ||
} | ||
|
||
try { | ||
(new B)->someReturningStaticMethod(); | ||
} catch (UnexpectedValueException $e) { | ||
// do nothing | ||
} | ||
|
||
echo "OK!", PHP_EOL; | ||
|
||
?> | ||
--EXPECT-- | ||
OK! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--TEST-- | ||
never return type: unacceptable cases: any return | ||
--FILE-- | ||
<?php | ||
|
||
function foo(): never { | ||
return "hello"; // not permitted in a never function | ||
} | ||
|
||
// Note the lack of function call: function validated at compile-time | ||
?> | ||
--EXPECTF-- | ||
Fatal error: A never function must not return in %s on line %d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--TEST-- | ||
never return type: unacceptable cases: empty return | ||
--FILE-- | ||
<?php | ||
|
||
function foo(): never { | ||
return; // not permitted in a never function | ||
} | ||
|
||
// Note the lack of function call: function validated at compile-time | ||
?> | ||
--EXPECTF-- | ||
Fatal error: A never function must not return in %s on line %d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--TEST-- | ||
never return type: unacceptable cases: implicit return | ||
--FILE-- | ||
<?php | ||
|
||
function foo(): never { | ||
if (false) { | ||
throw new Exception('bad'); | ||
} | ||
} | ||
|
||
foo(); | ||
?> | ||
--EXPECTF-- | ||
Fatal error: Uncaught TypeError: foo(): Nothing was expected to be returned in %s:%d | ||
Stack trace: | ||
#0 %s(%d): foo() | ||
#1 {main} | ||
thrown in %s on line %d | ||
muglug marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
--TEST-- | ||
never return type: never cannot return from finally | ||
--FILE-- | ||
<?php | ||
|
||
function foo() : never { | ||
try { | ||
throw new Exception('bad'); | ||
} finally { | ||
return; | ||
} | ||
} | ||
|
||
// Note the lack of function call: function validated at compile-time | ||
?> | ||
--EXPECTF-- | ||
Fatal error: A never function must not return in %s on line %d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
--TEST-- | ||
never return type: prevent unacceptable cases | ||
--FILE-- | ||
<?php | ||
|
||
class A | ||
{ | ||
public function bar(): never | ||
{ | ||
throw new \Exception('parent'); | ||
} | ||
} | ||
|
||
class B extends A | ||
{ | ||
public function bar(): string | ||
{ | ||
return "hello"; | ||
} | ||
} | ||
|
||
(new B)->bar(); | ||
|
||
?> | ||
--EXPECTF-- | ||
Fatal error: Declaration of B::bar(): string must be compatible with A::bar(): never in %s on line %d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--TEST-- | ||
never return type: not valid as a parameter type | ||
--FILE-- | ||
<?php | ||
|
||
function foobar(never $a) {} | ||
?> | ||
--EXPECTF-- | ||
Fatal error: never cannot be used as a parameter type in %s on line %d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--TEST-- | ||
never in reflection | ||
--FILE-- | ||
<?php | ||
|
||
function foo(): never {} | ||
|
||
$neverType = (new ReflectionFunction('foo'))->getReturnType(); | ||
|
||
echo $neverType->getName() . "\n"; | ||
var_dump($neverType->isBuiltin()); | ||
|
||
?> | ||
--EXPECT-- | ||
never | ||
bool(true) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--TEST-- | ||
never return type: never cannot return from throw expression | ||
--FILE-- | ||
<?php | ||
|
||
function foo() : never { | ||
return throw new Exception('bad'); | ||
} | ||
|
||
// Note the lack of function call: function validated at compile-time | ||
?> | ||
--EXPECTF-- | ||
Fatal error: A never function must not return in %s on line %d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
--TEST-- | ||
never type of __toString method | ||
--FILE-- | ||
<?php | ||
|
||
class A implements Stringable { | ||
public function __toString(): string { | ||
return "hello"; | ||
} | ||
} | ||
|
||
class B extends A { | ||
public function __toString(): never { | ||
throw new \Exception('not supported'); | ||
} | ||
} | ||
|
||
try { | ||
echo (string) (new B()); | ||
} catch (Exception $e) { | ||
// do nothing | ||
} | ||
|
||
echo "done"; | ||
|
||
?> | ||
--EXPECT-- | ||
done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--TEST-- | ||
Test typed properties disallow never | ||
--FILE-- | ||
<?php | ||
class Foo { | ||
public never $int; | ||
} | ||
|
||
$foo = new Foo(); | ||
?> | ||
--EXPECTF-- | ||
Fatal error: Property Foo::$int cannot have type never in %s on line 3 |
10 changes: 10 additions & 0 deletions
10
Zend/tests/type_declarations/union_types/never_with_class.phpt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--TEST-- | ||
Combining never with class type | ||
--FILE-- | ||
<?php | ||
|
||
function test(): T|never {} | ||
|
||
?> | ||
--EXPECTF-- | ||
Fatal error: never can only be used as a standalone type in %s on line %d |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.