Skip to content

Commit 2da94f8

Browse files
committed
Merge remote-tracking branch 'origin/1.12.x' into 2.0.x
2 parents edcc9e8 + d6412b8 commit 2da94f8

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

Diff for: src/Reflection/ClassReflection.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,7 @@ public function getActiveTemplateTypeMap(): TemplateTypeMap
13641364
if ($type instanceof ErrorType) {
13651365
$templateType = $templateTypeMap->getType($name);
13661366
if ($templateType !== null) {
1367-
return TemplateTypeHelper::resolveToBounds($templateType);
1367+
return TemplateTypeHelper::resolveToDefaults($templateType);
13681368
}
13691369
}
13701370

Diff for: src/Type/Generic/TemplateTypeHelper.php

+11
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ public static function resolveTemplateTypes(
6868
});
6969
}
7070

71+
public static function resolveToDefaults(Type $type): Type
72+
{
73+
return TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {
74+
if ($type instanceof TemplateType) {
75+
return $traverse($type->getDefault() ?? $type->getBound());
76+
}
77+
78+
return $traverse($type);
79+
});
80+
}
81+
7182
public static function resolveToBounds(Type $type): Type
7283
{
7384
return TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {

Diff for: src/Type/ObjectType.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ public function getTemplateType(string $ancestorClassName, string $templateTypeN
827827
return new MixedType(false);
828828
}
829829

830-
return $bound;
830+
return TemplateTypeHelper::resolveToDefaults($templateType);
831831
}
832832

833833
return $type;

Diff for: tests/PHPStan/Analyser/nsrt/bug-11899.php

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Bug11899;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
abstract class Test {}
8+
9+
interface InvertedQuestions {}
10+
11+
class SomeTest extends Test implements InvertedQuestions {}
12+
13+
/**
14+
* @template TTestType = Test
15+
* @property-read ?TTestType $test
16+
*/
17+
class UserTest {
18+
public function __get() : mixed {
19+
return new SomeTest();
20+
}
21+
}
22+
23+
function acceptUserTest1(UserTest $ut) : void {
24+
assertType('Bug11899\\UserTest', $ut);
25+
assertType('Bug11899\\Test|null', $ut->test);
26+
}
27+
28+
/**
29+
* @param UserTest<InvertedQuestions> $ut
30+
*/
31+
function acceptUserTest2(UserTest $ut) : void {
32+
assertType('Bug11899\\UserTest<Bug11899\\InvertedQuestions>', $ut);
33+
assertType('Bug11899\\InvertedQuestions|null', $ut->test);
34+
}

0 commit comments

Comments
 (0)