rfc:noreturn_type

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:noreturn_type [2021/03/10 17:59] – Add Ondrej's email mattbrownrfc:noreturn_type [2021/04/19 09:31] (current) nikic
Line 3: Line 3:
   * Date: 2021-03-10   * Date: 2021-03-10
   * Author: Matt Brown <php@muglug.com> & Ondřej Mirtes <ondrej@mirtes.cz>   * Author: Matt Brown <php@muglug.com> & Ondřej Mirtes <ondrej@mirtes.cz>
-  * Status: Under Discussion+  * Status: Implemented
   * Proposed Version: PHP 8.1   * Proposed Version: PHP 8.1
   * Implementation: https://github.com/php/php-src/pull/6761   * Implementation: https://github.com/php/php-src/pull/6761
Line 9: Line 9:
 ===== Introduction ===== ===== Introduction =====
  
-There has been a trend over the past few years that concepts initially just expressed in PHP docblocks eventually become native PHP types. +There has been a trend over the past few years that concepts initially just expressed in PHP docblocks eventually become native PHP types. Past examples are: [[https://wiki.php.net/rfc/scalar_type_hints_v5|scalar typehints]], [[https://wiki.php.net/rfc/return_types|return types]], [[https://wiki.php.net/rfc/union_types_v2|union types]], [[https://wiki.php.net/rfc/mixed_type_v2|mixed types]], and [[https://wiki.php.net/rfc/static_return_type|static types]].
- +
-Past examples are: [[https://wiki.php.net/rfc/scalar_type_hints_v5|scalar typehints]], [[https://wiki.php.net/rfc/return_types|return types]], [[https://wiki.php.net/rfc/union_types_v2|union types]], [[https://wiki.php.net/rfc/mixed_type_v2|mixed types]], and [[https://wiki.php.net/rfc/static_return_type|static types]].+
  
 Our static analysis tools currently provide support for '' @return noreturn '' docblocks to denote functions that always ''throw'' or ''exit''. Users of these tools have found that syntax useful to describe the behaviour of their own code, but we think it’s even more useful as a native return type, where PHP compile-time and runtime type-checks can guarantee its behaviour. Our static analysis tools currently provide support for '' @return noreturn '' docblocks to denote functions that always ''throw'' or ''exit''. Users of these tools have found that syntax useful to describe the behaviour of their own code, but we think it’s even more useful as a native return type, where PHP compile-time and runtime type-checks can guarantee its behaviour.
Line 22: Line 20:
  
 <code php> <code php>
-function redirect(string $uri) : noreturn {+function redirect(string $uri): noreturn {
     header('Location: ' . $uri);     header('Location: ' . $uri);
     exit();     exit();
 } }
  
-function redirectToLoginPage() : noreturn {+function redirectToLoginPage(): noreturn {
     redirect('/login');     redirect('/login');
 } }
Line 47: Line 45:
  
 <code php> <code php>
-function redirect(string $uri) : noreturn {+function redirect(string $uri): noreturn {
     if ($uri === '') {     if ($uri === '') {
         return; // Fatal error: A noreturn function must not return         return; // Fatal error: A noreturn function must not return
Line 59: Line 57:
  
 <code php> <code php>
-function redirect(string $uri) : noreturn {+function redirect(string $uri): noreturn {
     if ($uri !== '') {     if ($uri !== '') {
         header('Location: ' . $uri);         header('Location: ' . $uri);
Line 72: Line 70:
  
 <code php> <code php>
-function generateList(string $uri) : noreturn {+function generateList(string $uri): noreturn {
     yield 1;     yield 1;
     exit();     exit();
Line 100: Line 98:
 abstract class Person abstract class Person
 { {
-    abstract public function hasAgreedToTerms() : bool;+    abstract public function hasAgreedToTerms(): bool;
 } }
  
 class Kid extends Person class Kid extends Person
 { {
-    public function hasAgreedToTerms() : noreturn+    public function hasAgreedToTerms(): noreturn
     {     {
         throw new \Exception('Kids cannot legally agree to terms');         throw new \Exception('Kids cannot legally agree to terms');
Line 117: Line 115:
 abstract class Redirector abstract class Redirector
 { {
-    abstract public function execute() : noreturn;+    abstract public function execute(): noreturn;
 } }
  
 class BadRedirector extends Redirector class BadRedirector extends Redirector
 { {
-    public function execute() : void {} // Fatal error+    public function execute(): void {} // Fatal error 
 +
 +</code> 
 + 
 +Returning by reference with a ''noreturn'' type is allowed as well. 
 + 
 +<code php> 
 +class A { 
 +    public function &test(): int { ... } 
 +
 +class B extends A { 
 +    public function &test(): noreturn { throw new Exception; } 
 +
 +</code> 
 + 
 +Returning ''noreturn'' is also allowed in %%__%%toString methods: 
 + 
 +<code php> 
 +class A implements Stringable { 
 +    public function __toString(): string { 
 +        return "hello"; 
 +    } 
 +
 + 
 +class B extends A { 
 +    public function __toString(): noreturn { 
 +        throw new \Exception('not supported'); 
 +    }
 } }
 </code> </code>
Line 157: Line 182:
  
 <code php> <code php>
-function sayHello(string $name) : void {+function sayHello(string $name): void {
     echo "Hello $name";     echo "Hello $name";
 } }
Line 168: Line 193:
  
 <code php> <code php>
-function redirect(string $uri) : noreturn {+function redirect(string $uri): noreturn {
     header('Location: ' . $uri);     header('Location: ' . $uri);
     exit();     exit();
Line 185: Line 210:
 <code php> <code php>
 #[\NoReturn] #[\NoReturn]
-function redirectToLoginPage() : void {...}+function redirectToLoginPage(): void {...}
 </code> </code>
  
Line 191: Line 216:
  
 <code php> <code php>
-function redirectToLoginPage() : noreturn {...}+function redirectToLoginPage(): noreturn {...}
 </code> </code>
  
Line 198: Line 223:
 ==== Naming ==== ==== Naming ====
  
-Naming is hard, but we believe ''noreturn'' is the best name for this type.+Naming is hard. We each have different preferences.
  
 Arguments for ''noreturn'': Arguments for ''noreturn'':
Line 222: Line 247:
 Draft implementation here: https://github.com/php/php-src/pull/6761 Draft implementation here: https://github.com/php/php-src/pull/6761
  
-===== Proposed Voting Choices =====+===== Vote ===== 
 + 
 +Voting opens 2021-03-30 and 2021-04-13 at 11:00:00 AM EDT. 2/3 required to accept. 
 + 
 +<doodle title="Add noreturn type" auth="mattbrown" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle> 
 + 
 +Following vote requires simple majority:
  
-Yes/no vote for adding ''noreturn''+<doodle title="noreturn vs never" auth="mattbrown" voteType="single" closed="true"> 
 +   * noreturn 
 +   * never 
 +</doodle>
rfc/noreturn_type.1615399174.txt.gz · Last modified: 2021/03/10 17:59 by mattbrown