Skip to content

Commit 4fc6007

Browse files
phpstan-botclaude
andcommitted
Generalize trait $this check to cover property fetches and method calls
The previous fix only handled `$this` directly in trait context, but similar false positives occur with expressions like `$this->foo` when different classes using the trait define properties with different types. Introduced `isExpressionDependentOnThis()` helper that recursively checks if an expression is rooted in `$this`, covering Variable, PropertyFetch, and MethodCall nodes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b94b5d6 commit 4fc6007

2 files changed

Lines changed: 46 additions & 2 deletions

File tree

src/Rules/Comparison/ImpossibleCheckTypeHelper.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ public function findSpecifiedType(
310310
continue;
311311
}
312312

313-
if ($scope->isInTrait() && $sureType[0] instanceof Expr\Variable && $sureType[0]->name === 'this') {
313+
if ($scope->isInTrait() && self::isExpressionDependentOnThis($sureType[0])) {
314314
$results[] = TrinaryLogic::createMaybe();
315315
continue;
316316
}
@@ -341,7 +341,7 @@ public function findSpecifiedType(
341341
continue;
342342
}
343343

344-
if ($scope->isInTrait() && $sureNotType[0] instanceof Expr\Variable && $sureNotType[0]->name === 'this') {
344+
if ($scope->isInTrait() && self::isExpressionDependentOnThis($sureNotType[0])) {
345345
$results[] = TrinaryLogic::createMaybe();
346346
continue;
347347
}
@@ -391,6 +391,23 @@ private static function isSpecified(Scope $scope, Expr $node, Expr $expr): bool
391391
) && $scope->hasExpressionType($expr)->yes();
392392
}
393393

394+
private static function isExpressionDependentOnThis(Expr $expr): bool
395+
{
396+
if ($expr instanceof Expr\Variable && $expr->name === 'this') {
397+
return true;
398+
}
399+
400+
if ($expr instanceof Expr\PropertyFetch) {
401+
return self::isExpressionDependentOnThis($expr->var);
402+
}
403+
404+
if ($expr instanceof Expr\MethodCall) {
405+
return self::isExpressionDependentOnThis($expr->var);
406+
}
407+
408+
return false;
409+
}
410+
394411
/**
395412
* @param Node\Arg[] $args
396413
*/

tests/PHPStan/Rules/Comparison/data/bug-13023.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,30 @@ public function getRandom(): int
2323
return $value;
2424
}
2525
}
26+
27+
class SomeClass3
28+
{
29+
use MyTrait2;
30+
31+
public string $foo = 'foo';
32+
}
33+
34+
class SomeClass4
35+
{
36+
use MyTrait2;
37+
38+
public int $foo = 1;
39+
}
40+
41+
trait MyTrait2
42+
{
43+
public function getRandom(): int
44+
{
45+
$value = random_int(1, 100);
46+
if (\is_int($this->foo)) {
47+
return $value * $value;
48+
}
49+
50+
return $value;
51+
}
52+
}

0 commit comments

Comments
 (0)