rfc:typed_properties_v2

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:typed_properties_v2 [2019/01/03 14:05] – automatic promotion of arrays and objects nikicrfc:typed_properties_v2 [2019/01/11 16:16] (current) – Implemented nikic
Line 6: Line 6:
   * Implementation: https://github.com/php/php-src/pull/3313   * Implementation: https://github.com/php/php-src/pull/3313
   * Discussion: https://externals.io/message/102333 and https://externals.io/message/103148   * Discussion: https://externals.io/message/102333 and https://externals.io/message/103148
-  * Status: Accepted+  * Status: Implemented (in PHP 7.4)
  
 ===== Introduction ===== ===== Introduction =====
Line 1253: Line 1253:
 ===== Errata ===== ===== 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 instad.+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 ==== ==== Automatic promotion of arrays and objects ====
  
-PHP automatically initializes falsy values that are used as arrays or object 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.+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> <code php>
Line 1272: Line 1272:
 $prop->foobar = 123; // TypeError, because we can't assign stdClass to ?int $prop->foobar = 123; // TypeError, because we can't assign stdClass to ?int
 </code> </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 1277: Line 1311:
 Significant changes to the RFC are noted here. Significant changes to the RFC are noted here.
  
-  * 2018-01-03: Add errata: Automatic promotion of arrays and objects.+  * 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