From 692b5beeb724a55c660e4a921751e2b7cbed79a3 Mon Sep 17 00:00:00 2001 From: Caleb White Date: Fri, 12 Sep 2025 17:09:32 -0500 Subject: [PATCH] fix: checking optional properties in object shapes --- src/Type/ObjectShapeType.php | 20 ++-------------- .../Rules/Methods/CallMethodsRuleTest.php | 9 +++++++ .../PHPStan/Rules/Methods/data/bug-13511.php | 24 +++++++++++++++++++ 3 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 tests/PHPStan/Rules/Methods/data/bug-13511.php diff --git a/src/Type/ObjectShapeType.php b/src/Type/ObjectShapeType.php index 8b32331b36..332d63964f 100644 --- a/src/Type/ObjectShapeType.php +++ b/src/Type/ObjectShapeType.php @@ -176,15 +176,7 @@ public function accepts(Type $type, bool $strictTypes): AcceptsResult try { $otherProperty = $type->getProperty((string) $propertyName, $scope); } catch (MissingPropertyFromReflectionException) { - return AcceptsResult::createNo( - [ - sprintf( - '%s does not have property $%s.', - $type->describe(VerbosityLevel::typeOnly()), - $propertyName, - ), - ], - ); + continue; } if (!$otherProperty->isPublic()) { @@ -281,15 +273,7 @@ public function isSuperTypeOf(Type $type): IsSuperTypeOfResult try { $otherProperty = $type->getProperty((string) $propertyName, $scope); } catch (MissingPropertyFromReflectionException) { - return IsSuperTypeOfResult::createNo( - [ - sprintf( - '%s does not have property $%s.', - $type->describe(VerbosityLevel::typeOnly()), - $propertyName, - ), - ], - ); + continue; } if (!$otherProperty->isPublic()) { return IsSuperTypeOfResult::createNo(); diff --git a/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php b/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php index 73b0e4aee1..354b11b027 100644 --- a/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php +++ b/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php @@ -3666,4 +3666,13 @@ public function testBug3396(): void $this->analyse([__DIR__ . '/data/bug-3396.php'], []); } + public function testBug13511(): void + { + $this->checkThisOnly = false; + $this->checkNullables = true; + $this->checkUnionTypes = true; + $this->checkExplicitMixed = true; + $this->analyse([__DIR__ . '/data/bug-13511.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Methods/data/bug-13511.php b/tests/PHPStan/Rules/Methods/data/bug-13511.php new file mode 100644 index 0000000000..cf7efde5be --- /dev/null +++ b/tests/PHPStan/Rules/Methods/data/bug-13511.php @@ -0,0 +1,24 @@ +printInfo($user); +};