rfc:typed_properties_v2

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
rfc:typed_properties_v2 [2018/09/21 15:40]
nikic Revert incorrect change by third party
rfc:typed_properties_v2 [2019/01/11 16:16]
nikic Implemented
Line 5: Line 5:
   * Proposed PHP version: PHP 7.4   * Proposed PHP version: PHP 7.4
   * Implementation: https://github.com/php/php-src/pull/3313   * Implementation: https://github.com/php/php-src/pull/3313
-  * Status: In voting+  * Discussion: https://externals.io/message/102333 and https://externals.io/message/103148 
 +  * Status: Implemented (in PHP 7.4)
  
 ===== Introduction ===== ===== Introduction =====
Line 1245: Line 1246:
 As this is a language change, a 2/3 majority is required. As this is a language change, a 2/3 majority is required.
  
-<doodle title="Add support for typed properties as described in this RFC?" auth="bwoebi" voteType="single" closed="false">+<doodle title="Add support for typed properties as described in this RFC?" auth="bwoebi" voteType="single" closed="true">
    * Yes    * Yes
    * No    * No
 </doodle> </doodle>
 +
 +===== Errata =====
 +
 +During final implementation work after the RFC was accepted, a number of cases were encountered which weren't explicitly specified in the original RFC text. They are documented here instead.
 +
 +==== Automatic promotion of arrays and objects ====
 +
 +PHP automatically initializes falsy values that are used as arrays or objects to an empty array or ''stdClass'' respectively. When this happens with a typed property or a reference to a typed property, the property type must be compatible with an array or stdClass object.
 +
 +<code php>
 +class Test {
 +    public ?int $prop = null;
 +}
 +
 +$test = new Test;
 +$test->prop[] = 123;       // TypeError, because we can't assign array to ?int
 +$test->prop->foobar = 123; // TypeError, because we can't assign stdClass to ?int
 +
 +$prop =& $test->prop;
 +$prop[] = 123;       // TypeError, because we can't assign array to ?int
 +$prop->foobar = 123; // TypeError, because we can't assign stdClass to ?int
 +</code>
 +
 +==== Strictness of runtime-evaluated default values ====
 +
 +Default values for both parameters and properties always follow the strict typing semantics, independently of the strict typing mode that applies in a particular file. However, there is one exception to this rule: If a constant expression parameter default value cannot be evaluated during compilation, it follows the strictness mode of the file instead:
 +
 +<code php>
 +function foo(int $x = FOO) { // currently allowed
 +    var_dump($x);
 +}
 +define('FOO', '42');
 +foo();
 +</code>
 +
 +For typed properties we do not make such an exception and following code will generate a TypeError:
 +
 +<code php>
 +class Test {
 +    public int $x = FOO; // TypeError
 +}
 +define('FOO', '42');
 +var_dump(new Test);
 +</code>
 +
 +The reason for this choice is that evaluation of constant expressions at compile-time vs run-time is an optimization choice and should not result in behavioral differences. Whether a constant expression is evaluated during compilation depends on many factors, including code order and whether or not opcache is enabled. We believe that the current behavior of parameters is a bug, not an intentional choice.
 +
 +==== Incrementing/decrementing beyond the maximal/minimal value ====
 +
 +When a value is incremented beyond ''PHP_INT_MAX'' or decremented beyond ''PHP_INT_MIN'' it is converted into a floating-point value and incremented/decremented as a floating-point value. Additionally, under PHP's type verification rules (both strict //and// weak), assigning an out-of-range floating point value to an integer is illegal.
 +
 +As stated, this would result in the following peculiar behavior: Incrementing an ''int'' property past the maximal value would always be an error, because ''(float)PHP_INT_MAX + 1'' exceeds the integer range. However, decrementing an ''int'' property past the minimal value would only error on 32-bit systems. The reason is that on 64-bit systems ''(float)PHP_INT_MIN - 1'' is the same as ''(float)PHP_INT_MIN'', which is accurately representable as a double-precision floating point number and as such can be assigned back to an ''int'' property without error.
 +
 +As such, we would always generate an error on increment/decrement overflow, apart from the case of decrements on 64-bit systems.
 +
 +To avoid this, we instead define that incrementing/decrementing an ''int'' property past the maximal/minimal value always generates an error. It should be noted that this only affects the ''++'' and ''%%--%%'' operators. Overflows caused by other means are not handled specially.
  
 ===== Changelog ===== ===== Changelog =====
Line 1254: Line 1311:
 Significant changes to the RFC are noted here. Significant changes to the RFC are noted here.
  
 +  * 2019-01-07: Add errata: Increment/decrement overflow behavior.
 +  * 2019-01-03: Add errata: Strictness of runtime-evaluated default values.
 +  * 2019-01-03: Add errata: Automatic promotion of arrays and objects.
   * 2018-07-16: Add note about compatibility requirement on properties coming from traits.   * 2018-07-16: Add note about compatibility requirement on properties coming from traits.
   * 2018-07-10: Add shim header to make porting extension easy.   * 2018-07-10: Add shim header to make porting extension easy.
rfc/typed_properties_v2.txt · Last modified: 2019/01/11 16:16 by nikic