diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index a0038dbe0c..4f0b2f6536 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -2056,6 +2056,7 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression $directClassNames = TypeUtils::getDirectClassNames($argValueType); if (count($directClassNames) === 1) { $scopeClass = $directClassNames[0]; + $thisType = new ObjectType($scopeClass); } elseif ( $argValue instanceof Expr\ClassConstFetch && $argValue->name instanceof Node\Identifier @@ -2063,8 +2064,10 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression && $argValue->class instanceof Name ) { $scopeClass = $scope->resolveName($argValue->class); + $thisType = new ObjectType($scopeClass); } elseif ($argValueType instanceof ConstantStringType) { $scopeClass = $argValueType->getValue(); + $thisType = new ObjectType($scopeClass); } } $closureBindScope = $scope->enterClosureBind($thisType, $scopeClass); diff --git a/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php b/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php index c315315d10..717fe521fb 100644 --- a/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php +++ b/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php @@ -822,6 +822,10 @@ public function testClosureBind(): void 'Call to an undefined method CallClosureBind\Foo::nonexistentMethod().', 19, ], + [ + 'Call to an undefined method CallClosureBind\Bar::barMethod().', + 23, + ], [ 'Call to an undefined method CallClosureBind\Foo::nonexistentMethod().', 28, @@ -850,6 +854,10 @@ public function testArrowFunctionClosureBind(): void 'Call to an undefined method CallArrowFunctionBind\Foo::nonexistentMethod().', 27, ], + [ + 'Call to an undefined method CallArrowFunctionBind\Bar::barMethod().', + 29, + ], [ 'Call to an undefined method CallArrowFunctionBind\Foo::nonexistentMethod().', 31, diff --git a/tests/PHPStan/Rules/Properties/AccessPropertiesRuleTest.php b/tests/PHPStan/Rules/Properties/AccessPropertiesRuleTest.php index 7f423ce788..cb843caafc 100644 --- a/tests/PHPStan/Rules/Properties/AccessPropertiesRuleTest.php +++ b/tests/PHPStan/Rules/Properties/AccessPropertiesRuleTest.php @@ -484,4 +484,11 @@ public function testBug4527(): void $this->analyse([__DIR__ . '/data/bug-4527.php'], []); } + public function testBug4808(): void + { + $this->checkThisOnly = false; + $this->checkUnionTypes = true; + $this->analyse([__DIR__ . '/data/bug-4808.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Properties/data/bug-4808.php b/tests/PHPStan/Rules/Properties/data/bug-4808.php new file mode 100644 index 0000000000..938a1772b8 --- /dev/null +++ b/tests/PHPStan/Rules/Properties/data/bug-4808.php @@ -0,0 +1,24 @@ +x; + } +} + +class B extends A +{ + public function getPrivateProp(): bool + { + return \Closure::bind(function () { + return $this->x; + }, $this, A::class)(); + } +}