diff --git a/tests/PHPStan/Rules/Properties/AccessPropertiesInAssignRuleTest.php b/tests/PHPStan/Rules/Properties/AccessPropertiesInAssignRuleTest.php index 6fb0fe27d5d..433dc95e795 100644 --- a/tests/PHPStan/Rules/Properties/AccessPropertiesInAssignRuleTest.php +++ b/tests/PHPStan/Rules/Properties/AccessPropertiesInAssignRuleTest.php @@ -207,6 +207,25 @@ public function testBug13123(): void $this->analyse([__DIR__ . '/data/bug-13123.php'], []); } + #[RequiresPhp('>= 8.5')] + public function testBug14063(): void + { + $this->analyse([__DIR__ . '/data/bug-14063.php'], [ + [ + 'Assign to protected(set) property Bug14063\Obj::$value.', + 31, + ], + [ + 'Assign to protected(set) property Bug14063\Obj::$value.', + 34, + ], + [ + 'Assign to protected(set) property Bug14063\Base::$value.', + 38, + ], + ]); + } + #[RequiresPhp('>= 8.5')] public function testCloneWith(): void { diff --git a/tests/PHPStan/Rules/Properties/data/bug-14063.php b/tests/PHPStan/Rules/Properties/data/bug-14063.php new file mode 100644 index 00000000000..0dc05a8c80e --- /dev/null +++ b/tests/PHPStan/Rules/Properties/data/bug-14063.php @@ -0,0 +1,39 @@ += 8.5 + +declare(strict_types = 1); + +namespace Bug14063; + +final readonly class Obj +{ + public function __construct(public string $value) {} + + public function withValue(string $newValue): self + { + return clone($this, ['value' => $newValue]); + } +} + +readonly class Base +{ + public function __construct(public string $value) {} +} + +readonly class Child extends Base +{ + public function withValue(string $newValue): self + { + return clone($this, ['value' => $newValue]); + } +} + +$obj = new Obj('val'); +$newObj = clone($obj, ['value' => 'newVal']); + +function test(Obj $obj): void { + clone($obj, ['value' => 'newVal']); +} + +function testBase(Base $base): void { + clone($base, ['value' => 'newVal']); +}