I recently found out that constructor property promotion cannot be used for final properties. I propose that it become allowed. Thoughts? Would this need an RFC, or is this minor enough to be acceptable with just a mailing list discussion?
Background:
In the process of trying to help support PHP 8.4 syntax in PHPCS[1], I discovered that constructor property promotion cannot be used with final properties. I thought that this was a bug, and filed GH-17860 with the report[2]. But, in the discussion on the patch that I sent to fix the bug[3], I was told that this was intentionally omitted. So, now the bug is a feature request.
I recently found out that constructor property promotion cannot be used for final properties. I propose that it become allowed. Thoughts? Would this need an RFC, or is this minor enough to be acceptable with just a mailing list discussion?
Given the lack of engagement, I want to make it clear: unless somebody objects, maintainers have agreed to merge a PR implementing the feature in 2 weeks.
I recently found out that constructor property promotion cannot be used
for final properties. I propose that it become allowed. Thoughts? Would
this need an RFC, or is this minor enough to be acceptable with just a
mailing list discussion?
Given the lack of engagement, I want to make it clear: unless somebody
objects, maintainers have agreed to merge a PR implementing the feature in
2 weeks.
If you object, please speak up.
Can you clarify if the following would result in constructor property promotion or not:
class Foo {
public function __construct(
final string $bar,
) { }
}
On Fri, Mar 21, 2025 at 4:07 AM Tim Düsterhus <tim@bastelstu.be> wrote:
Can you clarify if the following would result in constructor property
promotion or not:
class Foo {
public function __construct(
final string $bar,
) { }
}
Best regards
Tim Düsterhus
Yes, that would result in constructor property promotion. I’ll need to retarget the original PR for master, but at https://github.com/php/php-src/pull/17861 you can see in Zend/tests/property_hooks/final_prop_promoted_2.phpt a very similar test case.
On Fri, Mar 21, 2025 at 4:07 AM Tim Düsterhus <tim@bastelstu.be> wrote:
Can you clarify if the following would result in constructor property
promotion or not:
class Foo {
public function __construct(
final string $bar,
) { }
}
Best regards
Tim Düsterhus
Yes, that would result in constructor property promotion. I’ll need to retarget the original PR for master, but at https://github.com/php/php-src/pull/17861 you can see in Zend/tests/property_hooks/final_prop_promoted_2.phpt a very similar test case.
I see. Good catch Tim.
Daniel, you don’t have this exact test case there.
Initially, in 8.0, only a visibility keyword would trigger the property promotion logic.
Later, in 8.1, also the readonly keyword would trigger this and make the property public, without the need to mention the visibility: https://3v4l.org/Co0gl
Now we want the same for the final keyword, to trigger the property promotion without having a visibility keyword,
because like readonly, it would not be applicable to a parameter, but just to a property?
On Fri, Mar 21, 2025 at 4:07 AM Tim Düsterhus <tim@bastelstu.be> wrote:
Can you clarify if the following would result in constructor property
promotion or not:
class Foo {
public function __construct(
final string $bar,
) { }
}
Best regards
Tim Düsterhus
Yes, that would result in constructor property promotion. I’ll need to retarget the original PR for master, but at https://github.com/php/php-src/pull/17861 you can see in Zend/tests/property_hooks/final_prop_promoted_2.phpt a very similar test case.
I see. Good catch Tim.
Daniel, you don’t have this exact test case there.
Initially, in 8.0, only a visibility keyword would trigger the property promotion logic.
Later, in 8.1, also the readonly keyword would trigger this and make the property public, without the need to mention the visibility: https://3v4l.org/Co0gl
Now we want the same for the final keyword, to trigger the property promotion without having a visibility keyword,
because like readonly, it would not be applicable to a parameter, but just to a property?
–
Alex
Sorry, I completely missed that part. Yes, that should trigger promotion, and if it doesn’t then that is a bug in my implementation. When I retarget the PR to master I’ll also add a test case for promotion from just using final.
On Fri, Mar 21, 2025 at 4:07 AM Tim Düsterhus <tim@bastelstu.be> wrote:
Can you clarify if the following would result in constructor property
promotion or not:
class Foo {
public function __construct(
final string $bar,
) { }
}
Best regards
Tim Düsterhus
Yes, that would result in constructor property promotion. I’ll need to retarget the original PR for master, but at https://github.com/php/php-src/pull/17861 you can see in Zend/tests/property_hooks/final_prop_promoted_2.phpt a very similar test case.
I see. Good catch Tim.
Daniel, you don’t have this exact test case there.
Initially, in 8.0, only a visibility keyword would trigger the property promotion logic.
Later, in 8.1, also the readonly keyword would trigger this and make the property public, without the need to mention the visibility: https://3v4l.org/Co0gl
Now we want the same for the final keyword, to trigger the property promotion without having a visibility keyword,
because like readonly, it would not be applicable to a parameter, but just to a property?
–
Alex
Sorry, I completely missed that part. Yes, that should trigger promotion, and if it doesn’t then that is a bug in my implementation. When I retarget the PR to master I’ll also add a test case for promotion from just using final.
Hi Daniel,
When discussing the Aviz RFC, I also wrote on this topic. (https://news-web.php.net/php.internals/123488)
The main issue being that if we ever decide to use the final modifier for a parameter, it would not be possible.
It is already now possible to use the readonly modifier for a parameter because of this, something I wasn’t aware of until this topic.
On the readonly doing the promotion by itself, I believe it was an internal decision (that we properly documented later), but it was not discussed on the mailing list as far as I know.
Also, I believe there might not be an actual test that validates this behavior.
Having said that, allowing final to trigger property promotion by itself is not such a problematic thing, IMO. I would have preferred forcing a visibility keyword to trigger property promotions, but the cat is out of the bag already.
Also, allowing the final modifier for constructor parameters to be transformed as the final modifier for promoted properties is fine.
I guess that if we ever decide to use a keyword for declared variables or parameters to disallow changing their values, we can go with some other keyword like const, val, etc.
To answer the original question: I'm not against this change, but as it is a syntax change, I think it does warrant an RFC, even if it's a small/easy one. That's a good way to flesh out the edge cases like that.
To answer the original question: I’m not against this change, but as it is a syntax change, I think it does warrant an RFC, even if it’s a small/easy one. That’s a good way to flesh out the edge cases like that.
–Larry Garfield
Okay, I’ve created https://wiki.php.net/rfc/final_promotion - I’ll send an official notification email separately, but just wanted to include a link in the original thread.