Skip to content

Commit 3cf11ad

Browse files
Fix 9654
1 parent 5878035 commit 3cf11ad

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

src/Rules/Classes/NewStaticRule.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\DependencyInjection\RegisteredRule;
8+
use PHPStan\Php\PhpVersion;
89
use PHPStan\Reflection\Php\PhpMethodReflection;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Rules\RuleErrorBuilder;
@@ -17,6 +18,11 @@
1718
final class NewStaticRule implements Rule
1819
{
1920

21+
public function __construct(
22+
private PhpVersion $phpVersion,
23+
) {
24+
}
25+
2026
public function getNodeType(): string
2127
{
2228
return Node\Expr\New_::class;
@@ -77,6 +83,20 @@ public function processNode(Node $node, Scope $scope): array
7783
}
7884
}
7985

86+
if (
87+
$this->phpVersion->supportsAbstractTraitMethods()
88+
&& $scope->isInTrait()
89+
) {
90+
$traitReflection = $scope->getTraitReflection();
91+
if ($traitReflection->hasConstructor()) {
92+
$traitConstructor = $traitReflection->getConstructor();
93+
94+
if ($traitConstructor instanceof PhpMethodReflection && $traitConstructor->isAbstract()) {
95+
return [];
96+
}
97+
}
98+
}
99+
80100
return $messages;
81101
}
82102

tests/PHPStan/Rules/Classes/NewStaticRuleTest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Rules\Classes;
44

5+
use PHPStan\Php\PhpVersion;
56
use PHPStan\Rules\Rule;
67
use PHPStan\Testing\RuleTestCase;
78

@@ -13,7 +14,9 @@ class NewStaticRuleTest extends RuleTestCase
1314

1415
protected function getRule(): Rule
1516
{
16-
return new NewStaticRule();
17+
return new NewStaticRule(
18+
new PhpVersion(PHP_VERSION_ID),
19+
);
1720
}
1821

1922
public function testRule(): void
@@ -39,4 +42,9 @@ public function testRuleWithConsistentConstructor(): void
3942
$this->analyse([__DIR__ . '/data/new-static-consistent-constructor.php'], []);
4043
}
4144

45+
public function testBug9654(): void
46+
{
47+
$this->analyse([__DIR__ . '/data/bug-9654.php'], []);
48+
}
49+
4250
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php // lint >= 8.0
2+
3+
namespace Bug9654;
4+
5+
trait Abc
6+
{
7+
abstract public function __construct();
8+
9+
public static function create(): static
10+
{
11+
return new static(); // this is safe as the constructor is defined abstract in this trait
12+
}
13+
}
14+
15+
class Foo
16+
{
17+
use Abc;
18+
19+
public function __construct() {
20+
21+
}
22+
}
23+
24+
class Bar
25+
{
26+
use Abc;
27+
28+
public function __construct(int $i = 0)
29+
{
30+
$i = $i*2;
31+
}
32+
}

0 commit comments

Comments
 (0)