From aa93ef60e39c94037d141b54c68a17f59e2042b6 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 17 Sep 2026 22:26:10 +0200 Subject: [PATCH] [TypeDeclaration] Skip TypedPropertyFromStrictConstructorRector on protected property redeclared in child class --- ...ected_property_redeclared_in_child.php.inc | 25 +++++++++++++++++++ .../Source/SomeFrame.php | 9 +++++++ .../Guard/PropertyTypeOverrideGuard.php | 5 +++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromStrictConstructorRector/Fixture/skip_protected_property_redeclared_in_child.php.inc create mode 100644 rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromStrictConstructorRector/Source/SomeFrame.php diff --git a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromStrictConstructorRector/Fixture/skip_protected_property_redeclared_in_child.php.inc b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromStrictConstructorRector/Fixture/skip_protected_property_redeclared_in_child.php.inc new file mode 100644 index 00000000000..626a225dba5 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromStrictConstructorRector/Fixture/skip_protected_property_redeclared_in_child.php.inc @@ -0,0 +1,25 @@ +frame = $frame; + } +} + +class ChildFrameReflower extends ParentFrameReflower +{ + protected $frame; + + public function __construct(SomeFrame $frame) + { + parent::__construct($frame); + } +} diff --git a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromStrictConstructorRector/Source/SomeFrame.php b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromStrictConstructorRector/Source/SomeFrame.php new file mode 100644 index 00000000000..69c43893caa --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromStrictConstructorRector/Source/SomeFrame.php @@ -0,0 +1,9 @@ +makePropertyTypedGuard->isLegal($property, $classReflection)) { + // protected property on a non-final class may be redeclared untyped in a child class, + // which would cause a covariance fatal error once only the parent is typed + $inlinePublic = ! $property->isProtected(); + if (! $this->makePropertyTypedGuard->isLegal($property, $classReflection, $inlinePublic)) { return false; }