Hi,
As PHP 7 currently is, if you write this:
public function foo(): integer {
return 12;
}
$bar = foo();
you'll get the following error:
Fatal error: Uncaught TypeError: Return value of foo() must be an
instance of integer, integer returned
Similarly, if you were to write this:
public function foo(): boolean {
return true;
}
$bar = $foo();
you'd get this:
Fatal error: Uncaught TypeError: Return value of foo() must be an
instance of boolean, boolean returned
These are confusing and unhelpful error messages. The long-form names of
types (integer, boolean) aren't accepted as type hints, only their
short-form names (int, bool) are. Yet we didn't reserve the names
'integer' and 'boolean' so we could produce a helpful error message, so
anyone who types these long names will have them interpreted as type
hints for (likely non-existant) classes named 'integer' or 'boolean'
respectively. That produces confusing error messages on its own, but
worse, type hint errors use 'integer' and 'boolean' to describe the
types of values expected or given. Together, these two issues mean you
get the two incredibly confusing error messages above.
This is not kind to the users of PHP. It will cause unneeded confusion.
This isn't even a theoretical case, that first example was based on a
real StackOverflow question.[0] Mistakenly typing 'integer' or 'boolean'
instead of 'int' and 'bool' is not at all an unlikely error, especially
since the PHP manual uses these in some places (we should probably fix
that at some point, and make it use PHP's actual syntax for return types
and variadics, but I digress...), and since the aforementioned type
error messages use them.
To avoid confusion, I would like it if we reserve 'integer' and
'boolean' alongside 'int' and 'bool', and make them produce an error if
used. This would catch out mistakes with people writing the wrong name
for the type hint, and as a bonus would prevent people from misreading
typehints for classes which actually have thse names, as no class with
that name would be allowed. However, we're getting close to release and
this might force some people to rename classes again if changed, causing
disruption, so we might not be able to do this.
Alongside or instead of that, though, we can do two other things to make
this situation better.
First, we could make type error messages use 'int' and 'bool'. This
feels somewhat wrong to me since integer and Boolean are the proper
English names for the types. But we do use the short names in some other
places, like var_dump, so this isn't so bad. This way, we get this
slightly clearer error:
Fatal error: Uncaught TypeError: Return value of foo() must be an
instance of integer, int returned
Second, we could add a helpful note to the TypeError message when the
type hint is for a class named 'integer' or 'boolean' and the value
passed was an integer or Boolean, respectively. My patch (based on
Anthony's original) for the earlier Scalar Type Hinting with Cast RFC
did this. This would make things even clearer:
Fatal error: Uncaught TypeError: Return value of foo() must be an
instance of integer, int returned (did you mean to use the type hint 'int'?)
Even if we can't reserve the names, I hope we can do the two other
suggestions in time for release.
By the way, this situation is at least partly my fault. For PHP 7 I
fixed zend_parse_parameters and userland type hint errors consistent
with regard to type names: always 'integer', never 'long' (which only
ever occured for the expectation, not what was actually given,
bizarrely), and also always 'float', never 'double'. I also made sure
is_int was an alias of is_long and not vice-versa. Alas, I made the
mistake of picking 'int' over 'integer' and 'bool' over 'boolean'.
Anyway, can we do something about this soon?
Thanks!
[0]
http://stackoverflow.com/questions/32665818/php-7-return-type-declarations-fatal-error
--
Andrea Faulds
http://ajf.me/
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php