Skip to content

Commit 088b9fa

Browse files
arnaud-lbondrejmirtes
authored andcommitted
Fix return type of PhpFunctionFromParserNodeReflection (fixes #2574)
1 parent 2d69ac7 commit 088b9fa

File tree

7 files changed

+91
-2
lines changed

7 files changed

+91
-2
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2585,7 +2585,11 @@ private function getPhpDocReturnType(?PhpDocBlock $phpDocBlock, ResolvedPhpDocBl
25852585
);
25862586
}
25872587

2588-
if (($phpDocBlock !== null && $phpDocBlock->isExplicit()) || $nativeReturnType->isSuperTypeOf($phpDocReturnType)->yes()) {
2588+
if ($phpDocBlock === null || $phpDocBlock->isExplicit()) {
2589+
return $phpDocReturnType;
2590+
}
2591+
2592+
if ($nativeReturnType->isSuperTypeOf(TemplateTypeHelper::resolveToBounds($phpDocReturnType))->yes()) {
25892593
return $phpDocReturnType;
25902594
}
25912595

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9521,6 +9521,13 @@ public function testArrayShapesInPhpDoc(
95219521
);
95229522
}
95239523

9524+
public function dataBug2574(): array
9525+
{
9526+
require_once __DIR__ . '/data/bug2574.php';
9527+
9528+
return $this->gatherAssertTypes(__DIR__ . '/data/bug2574.php');
9529+
}
9530+
95249531
public function dataBug2577(): array
95259532
{
95269533
require_once __DIR__ . '/data/bug2577.php';
@@ -9575,6 +9582,7 @@ public function dataStaticProperties(): array
95759582
}
95769583

95779584
/**
9585+
* @dataProvider dataBug2574
95789586
* @dataProvider dataBug2577
95799587
* @dataProvider dataGenerics
95809588
* @dataProvider dataGenericClassStringType
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Analyser\Bug2574;
4+
5+
use function PHPStan\Analyser\assertType;
6+
7+
abstract class Model {
8+
/** @return static */
9+
public function newInstance() {
10+
return new static();
11+
}
12+
}
13+
14+
class Model1 extends Model {
15+
}
16+
17+
/**
18+
* @template T of Model
19+
* @param T $m
20+
* @return T
21+
*/
22+
function foo(Model $m) : Model {
23+
assertType('T of Analyser\Bug2574\Model (function Analyser\Bug2574\foo(), argument)', $m);
24+
$instance = $m->newInstance();
25+
assertType('T of Analyser\Bug2574\Model (function Analyser\Bug2574\foo(), argument)', $m);
26+
return $instance;
27+
}
28+
29+
function test(): void {
30+
assertType('Analyser\Bug2574\Model1', foo(new Model1()));
31+
}

tests/PHPStan/Generics/GenericsIntegrationTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ public function dataTopics(): array
1414
['varyingAcceptor'],
1515
['classes'],
1616
['variance'],
17+
['bug2574'],
1718
['bug2577'],
1819
['bug2620'],
19-
['bug2627'],
2020
['bug2622'],
21+
['bug2627'],
2122
];
2223
}
2324

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Generics\Bug2574;
4+
5+
abstract class Model {
6+
/** @return static */
7+
public function newInstance() {
8+
return new static();
9+
}
10+
}
11+
12+
/**
13+
* @template T of Model
14+
* @param T $m
15+
* @return T
16+
*/
17+
function foo(Model $m) : Model {
18+
return $m->newInstance();
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"message": "Unsafe usage of new static().",
4+
"line": 8,
5+
"ignorable": true
6+
}
7+
]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Generics\Bug2574;
4+
5+
abstract class Model {
6+
/** @return static */
7+
public function newInstance() {
8+
return new static();
9+
}
10+
}
11+
12+
/**
13+
* @template T of Model
14+
* @param T $m
15+
* @return T
16+
*/
17+
function foo(Model $m) : Model {
18+
return $m->newInstance();
19+
}

0 commit comments

Comments
 (0)