Skip to content

Commit 73ea929

Browse files
committed
Test generics in TypesAssignedToPropertiesRule for hooked properties
1 parent dffa364 commit 73ea929

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

tests/PHPStan/Rules/Properties/TypesAssignedToPropertiesRuleTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,23 @@ public function testPropertyHooks(): void
741741
'Property AssignHookedProperties\Foo::$i (array<string>|int) does not accept array<int, int>.',
742742
27,
743743
],
744+
[
745+
'Property AssignHookedProperties\FooGenerics<int>::$a (int) does not accept string.',
746+
52,
747+
],
748+
[
749+
'Property AssignHookedProperties\FooGenerics<T>::$a (T) does not accept int.',
750+
61,
751+
'Type int is not always the same as T. It breaks the contract for some argument types, typically subtypes.',
752+
],
753+
[
754+
'Property AssignHookedProperties\FooGenericsParam<T>::$a (array<T>) does not accept array<T>|int.',
755+
76,
756+
],
757+
[
758+
'Property AssignHookedProperties\FooGenericsParam<int>::$a (array<int>|int) does not accept array<int, string>.',
759+
91,
760+
],
744761
]);
745762
}
746763

tests/PHPStan/Rules/Properties/data/assign-hooked-properties.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,76 @@ public function doFoo(): void
2828
}
2929

3030
}
31+
32+
/**
33+
* @template T
34+
*/
35+
class FooGenerics
36+
{
37+
38+
/** @var T */
39+
public $a {
40+
set {
41+
$this->a = $value;
42+
}
43+
}
44+
45+
/**
46+
* @param FooGenerics<int> $f
47+
* @return void
48+
*/
49+
public static function doFoo(self $f): void
50+
{
51+
$f->a = 1;
52+
$f->a = 'foo';
53+
}
54+
55+
/**
56+
* @param T $t
57+
*/
58+
public function doBar($t): void
59+
{
60+
$this->a = $t;
61+
$this->a = 1;
62+
}
63+
64+
}
65+
66+
/**
67+
* @template T
68+
*/
69+
class FooGenericsParam
70+
{
71+
72+
/** @var array<T> */
73+
public array $a {
74+
/** @param array<T>|int $value */
75+
set (array|int $value) {
76+
$this->a = $value; // not ok
77+
78+
if (is_array($value)) {
79+
$this->a = $value; // ok
80+
}
81+
}
82+
}
83+
84+
/**
85+
* @param FooGenericsParam<int> $f
86+
* @return void
87+
*/
88+
public static function doFoo(self $f): void
89+
{
90+
$f->a = [1]; // ok
91+
$f->a = ['foo']; // not ok
92+
}
93+
94+
/**
95+
* @param T $t
96+
*/
97+
public function doBar($t): void
98+
{
99+
$this->a = [$t]; // ok
100+
$this->a = 1; // ok
101+
}
102+
103+
}

0 commit comments

Comments
 (0)