com php-langspec: Void return type: spec/09-lexical-structure.md spec/11-statements.md spec/13-functions.md spec/19-grammar.md tests/functions/void_allowed.phpt tests/functions/void_ disallowed1.phpt tests/functions/void_disallowed2.p hpt tests/functions/void_parameter.phpt

[email protected] (Andrea Faulds) Fri, 05 Feb 2016 12:42:41 +0000
Newsgroups php.standards.cvs
Message-ID <[email protected]>
Commit:    ad1a8bdba48ed23f118fe743f6930d1d57cd8042
Author:    Andrea Faulds <[email protected]>         Fri, 5 Feb 2016 12:30:11 +0000
Parents:   115ff30f4010768c46d45e777bcc55f082b7d245
Branches:  master

Link:       http://git.php.net/?p=php-langspec.git;a=commitdiff;h=ad1a8bdba48ed23f118fe743f6930d1d57cd8042

Log:
Void return type

Changed paths:
  M  spec/09-lexical-structure.md
  M  spec/11-statements.md
  M  spec/13-functions.md
  M  spec/19-grammar.md
  A  tests/functions/void_allowed.phpt
  A  tests/functions/void_disallowed1.phpt
  A  tests/functions/void_disallowed2.phpt
  A  tests/functions/void_parameter.phpt


Diff:
diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md
index f8af64a..bb72aa4 100644
--- a/spec/09-lexical-structure.md
+++ b/spec/09-lexical-structure.md
@@ -269,7 +269,7 @@ Unless stated otherwise ([functions](13-functions.md#function-definitions),
 
 Names beginning with two underscores (__) are reserved by the PHP language and should not be defined by the user code.
 
-The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, and `TRUE`.
+The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, `TRUE` and `void`.
 
 The following names are reserved for future use and should not be used as the names of classes, interfaces, or traits: `mixed`, `numeric`, `object`, and `resource`.
 
diff --git a/spec/11-statements.md b/spec/11-statements.md
index 415f1f9..6a11b60 100644
--- a/spec/11-statements.md
+++ b/spec/11-statements.md
@@ -903,6 +903,10 @@ by value or byRef. If *expression* is omitted the value `NULL` is used.
 If execution flows into the closing brace (`}`) of a function, `return
 NULL;` is implied.
 
+Explicit `return` statements with *expression* given are not permitted within a
+function with a `void` [return type](13-functions.md#return-typing) and MUST
+cause a compile-time fatal error.
+
 A function may have any number of `return` statements, whose returned
 values may have different types.
 
diff --git a/spec/13-functions.md b/spec/13-functions.md
index 850ad0e..247c344 100644
--- a/spec/13-functions.md
+++ b/spec/13-functions.md
@@ -74,6 +74,7 @@ A function is called via the function-call operator [`()`](10-expressions.md#fun
 
   <i>return-type:</i>
     : <i>type-declaration</i>
+    : void
 
   <i>type-declaration:</i>
     array
@@ -185,6 +186,9 @@ be compatible with the defined type, using the same rules as for parameter type
 are not allowed for typed returns. If the value of the [`return` statement](11-statements.md#the-return-statement)
 does not pass the type check, a fatal error is produced.
 
+The `void` type is a special type that can only be used as a return type, and
+not in other contexts. It has no effect at runtime, see the [`return` statement](11-statements.md#the-return-statement).
+
 ## Type check modes
 
 The type checking can be performed in two modes, strict and coercive (default). 
diff --git a/spec/19-grammar.md b/spec/19-grammar.md
index 2918d24..bb1f77e 100644
--- a/spec/19-grammar.md
+++ b/spec/19-grammar.md
@@ -1035,6 +1035,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
   <i>return-type:</i>
     : <i>type-declaration</i>
+    : void
 
   <i>type-declaration:</i>
     array
diff --git a/tests/functions/void_allowed.phpt b/tests/functions/void_allowed.phpt
new file mode 100644
index 0000000..8f07c73
--- /dev/null
+++ b/tests/functions/void_allowed.phpt
@@ -0,0 +1,20 @@
+--TEST--
+void return type: acceptable cases
+--FILE--
+<?php
+
+function foo(): void {
+    // okay
+}
+
+foo();
+
+function bar(): void {
+    return; // okay
+}
+
+bar();
+
+echo "OK!", PHP_EOL;
+--EXPECT--
+OK!
diff --git a/tests/functions/void_disallowed1.phpt b/tests/functions/void_disallowed1.phpt
new file mode 100644
index 0000000..b20f129
--- /dev/null
+++ b/tests/functions/void_disallowed1.phpt
@@ -0,0 +1,12 @@
+--TEST--
+void return type: unacceptable cases: explicit NULL return
+--FILE--
+<?php
+
+function foo(): void {
+    return NULL; // not permitted in a void function
+}
+
+// Note the lack of function call: function validated at compile-time
+--EXPECTF--
+Fatal error: A void function must not return a value in %s on line %d
diff --git a/tests/functions/void_disallowed2.phpt b/tests/functions/void_disallowed2.phpt
new file mode 100644
index 0000000..7bbc3ac
--- /dev/null
+++ b/tests/functions/void_disallowed2.phpt
@@ -0,0 +1,12 @@
+--TEST--
+void return type: unacceptable cases: explicit return of some other value
+--FILE--
+<?php
+
+function foo(): void {
+    return -1; // not permitted in a void function
+}
+
+// Note the lack of function call: function validated at compile-time
+--EXPECTF--
+Fatal error: A void function must not return a value in %s on line %d
diff --git a/tests/functions/void_parameter.phpt b/tests/functions/void_parameter.phpt
new file mode 100644
index 0000000..4c6e918
--- /dev/null
+++ b/tests/functions/void_parameter.phpt
@@ -0,0 +1,8 @@
+--TEST--
+void return type: not valid as a parameter type
+--FILE--
+<?php
+
+function foobar(void $a) {}
+--EXPECTF--
+Fatal error: void cannot be used as a parameter type in %s on line %d