Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.12.x' into 2.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Nov 11, 2024
2 parents edcc9e8 + d6412b8 commit 2da94f8
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Reflection/ClassReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1364,7 +1364,7 @@ public function getActiveTemplateTypeMap(): TemplateTypeMap
if ($type instanceof ErrorType) {
$templateType = $templateTypeMap->getType($name);
if ($templateType !== null) {
return TemplateTypeHelper::resolveToBounds($templateType);
return TemplateTypeHelper::resolveToDefaults($templateType);
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/Type/Generic/TemplateTypeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ public static function resolveTemplateTypes(
});
}

public static function resolveToDefaults(Type $type): Type
{
return TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {
if ($type instanceof TemplateType) {
return $traverse($type->getDefault() ?? $type->getBound());
}

return $traverse($type);
});
}

public static function resolveToBounds(Type $type): Type
{
return TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {
Expand Down
2 changes: 1 addition & 1 deletion src/Type/ObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ public function getTemplateType(string $ancestorClassName, string $templateTypeN
return new MixedType(false);
}

return $bound;
return TemplateTypeHelper::resolveToDefaults($templateType);
}

return $type;
Expand Down
34 changes: 34 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-11899.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Bug11899;

use function PHPStan\Testing\assertType;

abstract class Test {}

interface InvertedQuestions {}

class SomeTest extends Test implements InvertedQuestions {}

/**
* @template TTestType = Test
* @property-read ?TTestType $test
*/
class UserTest {
public function __get() : mixed {
return new SomeTest();
}
}

function acceptUserTest1(UserTest $ut) : void {
assertType('Bug11899\\UserTest', $ut);
assertType('Bug11899\\Test|null', $ut->test);
}

/**
* @param UserTest<InvertedQuestions> $ut
*/
function acceptUserTest2(UserTest $ut) : void {
assertType('Bug11899\\UserTest<Bug11899\\InvertedQuestions>', $ut);
assertType('Bug11899\\InvertedQuestions|null', $ut->test);
}

0 comments on commit 2da94f8

Please sign in to comment.