Allow promoted readonly properties to be reassigned once in constructor#20996
Allow promoted readonly properties to be reassigned once in constructor#20996nicolas-grekas wants to merge 7 commits intophp:masterfrom
Conversation
1667954 to
e8009a7
Compare
|
Implementation is now ready. |
|
RFC published at https://wiki.php.net/rfc/promoted_readonly_constructor_reassign |
e8009a7 to
3ccacde
Compare
f36150c to
e051b93
Compare
TimWolla
left a comment
There was a problem hiding this comment.
A number of comments for the tests. Didn't yet look at all of them.
d5b3e4c to
67be986
Compare
84228eb to
425081c
Compare
881a8e9 to
74406a1
Compare
|
@nicolas-grekas It looks like the function JIT is failing (this JIT was previously not tested in PRs). I started a run of the real-time benchmark. I've tried this already last week but it failed for some reason, not sure if the failure was related to the changes. The valgrind benchmark shows a regression of 0.3% for Symfony/Wordpress. Not huge but not insignificant (nowadays we fight a lot for these small percentages). |
AWS x86_64 (c6id.metal)
Laravel 12.11.0 demo app - 50 iterations, 50 warmups, 100 requests (sec)
Symfony 2.8.0 demo app - 50 iterations, 50 warmups, 100 requests (sec)
Wordpress 6.9 main page - 50 iterations, 20 warmups, 20 requests (sec)
bench.php - 50 iterations, 20 warmups, 2 requests (sec)
|
ecec79b to
15a0ae3
Compare
|
@nicolas-grekas Sorry for being late to the conversation. Have you considered implementing this solely in the slow readonly error path? I.e. just before emitting the "must not not modify readonly property" error, you could check whether the property is being modified within the constructor. This would allow multiple assignments within the constructor, which I find acceptable. But maybe you can even disallow multiple assignments within the constructor through another property flag. |
bdbf6b8 to
30e9c05
Compare
|
A "slow readonly error path only" implementation wouldn't preserve the desired semantics, because it cannot distinguish these two cases without extra transient state:
Patch updated with perf changes, hopefully removing that previous 0.3%. Let me know. |
30e9c05 to
1e00cef
Compare
|
I think there might be ways to achieve this behavior with less complexity. For example, the emitted assignments for readonly in the constructor could be preceded by a check that asserts properties are uninitialized when the constructor is called. This prevents multiple constructor calls. Then, the slow path could add a property flag to indicate the property has been assigned a second time, to prevent further reassignments within the constructor. |
71a2c3f to
e201e69
Compare
|
LLM-assisted response - might help reason about your proposal @iluuu1994 , and doesn't mean you're wrong:
|
AWS x86_64 (c6id.metal)
Laravel 12.11.0 demo app - 50 iterations, 50 warmups, 100 requests (sec)
Symfony 2.8.0 demo app - 50 iterations, 50 warmups, 100 requests (sec)
Wordpress 6.9 main page - 50 iterations, 20 warmups, 20 requests (sec)
bench.php - 50 iterations, 20 warmups, 2 requests (sec)
|
e201e69 to
6b37b86
Compare
6b37b86 to
19193f2
Compare
AWS x86_64 (c6id.metal)
Laravel 12.11.0 demo app - 50 iterations, 50 warmups, 100 requests (sec)
Symfony 2.8.0 demo app - 50 iterations, 50 warmups, 100 requests (sec)
Wordpress 6.9 main page - 50 iterations, 20 warmups, 20 requests (sec)
bench.php - 50 iterations, 20 warmups, 2 requests (sec)
|
I find it quite annoying that readonly properties play badly with CPP (constructor property promotion).
Doing simple processing of any argument before assigning it to a readonly property forces opting out of CPP.
This PR allows setting once a readonly property in the body of a constructor after the property was previously set using CPP.
Before this PR (CPP not possible):
After this PR:
This allows keeping properties declaration in its compact form.
I'll submit an RFC of course but would also welcome early feedback here before.