From fa22c84cfab796aaf5f7422d8a128e93eda94d22 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sun, 19 Oct 2025 19:41:39 +0200 Subject: [PATCH 1/3] Improve get_class return type --- .../GetClassDynamicReturnTypeExtension.php | 50 +++++++++-------- tests/PHPStan/Analyser/nsrt/bug-4890.php | 53 +++++++++++++++++++ tests/PHPStan/Analyser/nsrt/generics.php | 2 +- ...mpossibleCheckTypeFunctionCallRuleTest.php | 6 +++ .../Rules/Comparison/data/bug-4890b.php | 18 +++++++ 5 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 tests/PHPStan/Analyser/nsrt/bug-4890.php create mode 100644 tests/PHPStan/Rules/Comparison/data/bug-4890b.php diff --git a/src/Type/Php/GetClassDynamicReturnTypeExtension.php b/src/Type/Php/GetClassDynamicReturnTypeExtension.php index 14a06d90c0..487504a7d8 100644 --- a/src/Type/Php/GetClassDynamicReturnTypeExtension.php +++ b/src/Type/Php/GetClassDynamicReturnTypeExtension.php @@ -14,11 +14,12 @@ use PHPStan\Type\Generic\GenericClassStringType; use PHPStan\Type\Generic\TemplateType; use PHPStan\Type\IntersectionType; -use PHPStan\Type\MixedType; +use PHPStan\Type\ObjectShapeType; use PHPStan\Type\ObjectType; use PHPStan\Type\ObjectWithoutClassType; use PHPStan\Type\StaticType; use PHPStan\Type\Type; +use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypeTraverser; use PHPStan\Type\TypeUtils; use PHPStan\Type\UnionType; @@ -66,30 +67,35 @@ static function (Type $type, callable $traverse): Type { return new GenericClassStringType(new ObjectType($type->getClassName())); } - $objectClassNames = $type->getObjectClassNames(); - if ($type instanceof TemplateType && $objectClassNames === []) { - if ($type instanceof ObjectWithoutClassType) { - return new GenericClassStringType($type); - } - - return new UnionType([ - new GenericClassStringType($type), - new ConstantBooleanType(false), - ]); - } elseif ($type instanceof MixedType) { - return new UnionType([ - new ClassStringType(), - new ConstantBooleanType(false), - ]); - } elseif ($type instanceof StaticType) { - return new GenericClassStringType($type->getStaticObjectType()); - } elseif ($objectClassNames !== []) { - return new GenericClassStringType($type); - } elseif ($type instanceof ObjectWithoutClassType) { + if ($type instanceof ObjectShapeType) { return new ClassStringType(); } - return new ConstantBooleanType(false); + $isObject = $type->isObject(); + if ($isObject->no()) { + return new ConstantBooleanType(false); + } + + if ($type instanceof StaticType) { + $objectType = $type->getStaticObjectType(); + } else { + $objectType = TypeCombinator::intersect($type, new ObjectWithoutClassType()); + } + + if (!$objectType instanceof TemplateType && $objectType instanceof ObjectWithoutClassType) { + $classStringType = new ClassStringType(); + } else { + $classStringType = new GenericClassStringType($objectType); + } + + if ($isObject->yes()) { + return $classStringType; + } + + return new UnionType([ + $classStringType, + new ConstantBooleanType(false), + ]); }, ); } diff --git a/tests/PHPStan/Analyser/nsrt/bug-4890.php b/tests/PHPStan/Analyser/nsrt/bug-4890.php new file mode 100644 index 0000000000..0dbd26de19 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-4890.php @@ -0,0 +1,53 @@ +', get_class($entity)); + + if ($entity instanceof Proxy) { + assertType('class-string', get_class($entity)); + } + + $class = $entity instanceof Proxy + ? get_parent_class($entity) + : get_class($entity); + assert(is_string($class)); + + } + + public function updateProp(object $entity): void + { + assertType('class-string', get_class($entity)); + assert(property_exists($entity, 'myProp')); + assertType('class-string', get_class($entity)); + + if ($entity instanceof Proxy) { + assertType('class-string', get_class($entity)); + } + + $class = $entity instanceof Proxy + ? get_parent_class($entity) + : get_class($entity); + assert(is_string($class)); + } + + /** + * @param object{foo: self, bar: int, baz?: string} $entity + */ + public function updateObjectShape($entity): void + { + assertType('class-string', get_class($entity)); + assert(property_exists($entity, 'foo')); + assertType('class-string', get_class($entity)); + } +} diff --git a/tests/PHPStan/Analyser/nsrt/generics.php b/tests/PHPStan/Analyser/nsrt/generics.php index 1968fab471..23f3a1e6c0 100644 --- a/tests/PHPStan/Analyser/nsrt/generics.php +++ b/tests/PHPStan/Analyser/nsrt/generics.php @@ -1316,7 +1316,7 @@ function arrayOfGenericClassStrings(array $a): void function getClassOnTemplateType($a, $b, $c, $d, $object, $mixed, $tObject) { assertType( - 'class-string|false', + 'class-string|false', get_class($a) ); assertType( diff --git a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php index b6f79eeeeb..4a1059ffba 100644 --- a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php @@ -927,6 +927,12 @@ public function testLooseComparisonAgainstEnumsNoPhpdoc(): void $this->analyse([__DIR__ . '/data/loose-comparison-against-enums.php'], $issues); } + public function testBug4890b(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-4890b.php'], []); + } + public function testBug10502(): void { $tipText = 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.'; diff --git a/tests/PHPStan/Rules/Comparison/data/bug-4890b.php b/tests/PHPStan/Rules/Comparison/data/bug-4890b.php new file mode 100644 index 0000000000..8f31e109b3 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-4890b.php @@ -0,0 +1,18 @@ + Date: Sat, 6 Dec 2025 13:41:20 +0100 Subject: [PATCH 2/3] Remove condition --- src/Type/Php/GetClassDynamicReturnTypeExtension.php | 5 ----- tests/PHPStan/Analyser/nsrt/bug-4890.php | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Type/Php/GetClassDynamicReturnTypeExtension.php b/src/Type/Php/GetClassDynamicReturnTypeExtension.php index 487504a7d8..e363214cb0 100644 --- a/src/Type/Php/GetClassDynamicReturnTypeExtension.php +++ b/src/Type/Php/GetClassDynamicReturnTypeExtension.php @@ -14,7 +14,6 @@ use PHPStan\Type\Generic\GenericClassStringType; use PHPStan\Type\Generic\TemplateType; use PHPStan\Type\IntersectionType; -use PHPStan\Type\ObjectShapeType; use PHPStan\Type\ObjectType; use PHPStan\Type\ObjectWithoutClassType; use PHPStan\Type\StaticType; @@ -67,10 +66,6 @@ static function (Type $type, callable $traverse): Type { return new GenericClassStringType(new ObjectType($type->getClassName())); } - if ($type instanceof ObjectShapeType) { - return new ClassStringType(); - } - $isObject = $type->isObject(); if ($isObject->no()) { return new ConstantBooleanType(false); diff --git a/tests/PHPStan/Analyser/nsrt/bug-4890.php b/tests/PHPStan/Analyser/nsrt/bug-4890.php index 0dbd26de19..4c63fe7712 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-4890.php +++ b/tests/PHPStan/Analyser/nsrt/bug-4890.php @@ -46,8 +46,8 @@ public function updateProp(object $entity): void */ public function updateObjectShape($entity): void { - assertType('class-string', get_class($entity)); + assertType('class-string', get_class($entity)); assert(property_exists($entity, 'foo')); - assertType('class-string', get_class($entity)); + assertType('class-string', get_class($entity)); } } From d30f64a5bf3978b4131b70756eaa1abe2e2310ad Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sat, 6 Dec 2025 14:28:41 +0100 Subject: [PATCH 3/3] Introduce new method --- src/Type/Accessory/HasMethodType.php | 6 +++++ src/Type/Accessory/HasPropertyType.php | 6 +++++ src/Type/ClosureType.php | 5 ++++ src/Type/Enum/EnumCaseObjectType.php | 6 +++++ src/Type/Generic/TemplateMixedType.php | 5 ++++ .../TemplateObjectWithoutClassType.php | 5 ++++ src/Type/IntersectionType.php | 5 ++++ src/Type/MixedType.php | 5 ++++ src/Type/NeverType.php | 5 ++++ src/Type/NonexistentParentClassType.php | 5 ++++ src/Type/ObjectShapeType.php | 6 +++++ src/Type/ObjectType.php | 6 +++++ src/Type/ObjectWithoutClassType.php | 5 ++++ .../GetClassDynamicReturnTypeExtension.php | 24 +------------------ src/Type/StaticType.php | 5 ++++ src/Type/StrictMixedType.php | 5 ++++ src/Type/Traits/LateResolvableTypeTrait.php | 5 ++++ src/Type/Traits/MaybeObjectTypeTrait.php | 6 +++++ src/Type/Traits/NonObjectTypeTrait.php | 5 ++++ src/Type/Type.php | 2 ++ src/Type/UnionType.php | 5 ++++ tests/PHPStan/Analyser/nsrt/bug-4890.php | 4 ++-- tests/PHPStan/Analyser/nsrt/generics.php | 2 +- 23 files changed, 107 insertions(+), 26 deletions(-) diff --git a/src/Type/Accessory/HasMethodType.php b/src/Type/Accessory/HasMethodType.php index b59a77c788..0cf030e2c8 100644 --- a/src/Type/Accessory/HasMethodType.php +++ b/src/Type/Accessory/HasMethodType.php @@ -14,6 +14,7 @@ use PHPStan\Type\AcceptsResult; use PHPStan\Type\CompoundType; use PHPStan\Type\ErrorType; +use PHPStan\Type\Generic\GenericClassStringType; use PHPStan\Type\IntersectionType; use PHPStan\Type\IsSuperTypeOfResult; use PHPStan\Type\StringType; @@ -57,6 +58,11 @@ public function getObjectClassReflections(): array return []; } + public function getClassStringType(): Type + { + return new GenericClassStringType($this); + } + private function getCanonicalMethodName(): string { return strtolower($this->methodName); diff --git a/src/Type/Accessory/HasPropertyType.php b/src/Type/Accessory/HasPropertyType.php index ba2dbf8892..c164e62592 100644 --- a/src/Type/Accessory/HasPropertyType.php +++ b/src/Type/Accessory/HasPropertyType.php @@ -10,6 +10,7 @@ use PHPStan\Type\AcceptsResult; use PHPStan\Type\CompoundType; use PHPStan\Type\ErrorType; +use PHPStan\Type\Generic\GenericClassStringType; use PHPStan\Type\IntersectionType; use PHPStan\Type\IsSuperTypeOfResult; use PHPStan\Type\Traits\NonGeneralizableTypeTrait; @@ -51,6 +52,11 @@ public function getObjectClassReflections(): array return []; } + public function getClassStringType(): Type + { + return new GenericClassStringType($this); + } + public function getConstantStrings(): array { return []; diff --git a/src/Type/ClosureType.php b/src/Type/ClosureType.php index 49bbfe8c1b..7e7da791f9 100644 --- a/src/Type/ClosureType.php +++ b/src/Type/ClosureType.php @@ -295,6 +295,11 @@ public function isObject(): TrinaryLogic return $this->objectType->isObject(); } + public function getClassStringType(): Type + { + return $this->objectType->getClassStringType(); + } + public function isEnum(): TrinaryLogic { return $this->objectType->isEnum(); diff --git a/src/Type/Enum/EnumCaseObjectType.php b/src/Type/Enum/EnumCaseObjectType.php index ab1091846a..e77e8837f4 100644 --- a/src/Type/Enum/EnumCaseObjectType.php +++ b/src/Type/Enum/EnumCaseObjectType.php @@ -18,6 +18,7 @@ use PHPStan\Type\CompoundType; use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\GeneralizePrecision; +use PHPStan\Type\Generic\GenericClassStringType; use PHPStan\Type\IsSuperTypeOfResult; use PHPStan\Type\NeverType; use PHPStan\Type\ObjectType; @@ -217,6 +218,11 @@ public function getEnumCases(): array return [$this]; } + public function getClassStringType(): Type + { + return new GenericClassStringType(new ObjectType($this->getClassName())); + } + public function toPhpDocNode(): TypeNode { return new ConstTypeNode( diff --git a/src/Type/Generic/TemplateMixedType.php b/src/Type/Generic/TemplateMixedType.php index 8160633fc3..d7729cc353 100644 --- a/src/Type/Generic/TemplateMixedType.php +++ b/src/Type/Generic/TemplateMixedType.php @@ -63,4 +63,9 @@ public function toStrictMixedType(): TemplateStrictMixedType ); } + public function getClassStringType(): Type + { + return new GenericClassStringType($this); + } + } diff --git a/src/Type/Generic/TemplateObjectWithoutClassType.php b/src/Type/Generic/TemplateObjectWithoutClassType.php index 7d6aebc6f9..68e259132c 100644 --- a/src/Type/Generic/TemplateObjectWithoutClassType.php +++ b/src/Type/Generic/TemplateObjectWithoutClassType.php @@ -36,4 +36,9 @@ public function __construct( $this->default = $default; } + public function getClassStringType(): Type + { + return new GenericClassStringType($this); + } + } diff --git a/src/Type/IntersectionType.php b/src/Type/IntersectionType.php index 16cb33d2dd..7999a06efd 100644 --- a/src/Type/IntersectionType.php +++ b/src/Type/IntersectionType.php @@ -497,6 +497,11 @@ public function isObject(): TrinaryLogic return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isObject()); } + public function getClassStringType(): Type + { + return $this->intersectTypes(static fn (Type $type): Type => $type->getClassStringType()); + } + public function isEnum(): TrinaryLogic { return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isEnum()); diff --git a/src/Type/MixedType.php b/src/Type/MixedType.php index ad8d4fbfb1..96ca580228 100644 --- a/src/Type/MixedType.php +++ b/src/Type/MixedType.php @@ -386,6 +386,11 @@ public function isObject(): TrinaryLogic return TrinaryLogic::createMaybe(); } + public function getClassStringType(): Type + { + return new ClassStringType(); + } + public function isEnum(): TrinaryLogic { if ($this->subtractedType !== null) { diff --git a/src/Type/NeverType.php b/src/Type/NeverType.php index 5fc9a05280..9f52726739 100644 --- a/src/Type/NeverType.php +++ b/src/Type/NeverType.php @@ -113,6 +113,11 @@ public function isObject(): TrinaryLogic return TrinaryLogic::createNo(); } + public function getClassStringType(): Type + { + return new NeverType(); + } + public function isEnum(): TrinaryLogic { return TrinaryLogic::createNo(); diff --git a/src/Type/NonexistentParentClassType.php b/src/Type/NonexistentParentClassType.php index 1d5153f731..af0e0399a9 100644 --- a/src/Type/NonexistentParentClassType.php +++ b/src/Type/NonexistentParentClassType.php @@ -52,6 +52,11 @@ public function isObject(): TrinaryLogic return TrinaryLogic::createYes(); } + public function getClassStringType(): Type + { + return new ClassStringType(); + } + public function isEnum(): TrinaryLogic { return TrinaryLogic::createNo(); diff --git a/src/Type/ObjectShapeType.php b/src/Type/ObjectShapeType.php index 361190316b..381e6fd429 100644 --- a/src/Type/ObjectShapeType.php +++ b/src/Type/ObjectShapeType.php @@ -21,6 +21,7 @@ use PHPStan\Type\Accessory\HasPropertyType; use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Constant\ConstantStringType; +use PHPStan\Type\Generic\GenericClassStringType; use PHPStan\Type\Generic\TemplateTypeMap; use PHPStan\Type\Generic\TemplateTypeVariance; use PHPStan\Type\Traits\NonGeneralizableTypeTrait; @@ -89,6 +90,11 @@ public function getObjectClassReflections(): array return []; } + public function getClassStringType(): Type + { + return new GenericClassStringType($this); + } + public function hasProperty(string $propertyName): TrinaryLogic { return $this->hasInstanceProperty($propertyName); diff --git a/src/Type/ObjectType.php b/src/Type/ObjectType.php index 3b7a72baaa..3de4ce9fe0 100644 --- a/src/Type/ObjectType.php +++ b/src/Type/ObjectType.php @@ -40,6 +40,7 @@ use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\Enum\EnumCaseObjectType; +use PHPStan\Type\Generic\GenericClassStringType; use PHPStan\Type\Generic\GenericObjectType; use PHPStan\Type\Generic\TemplateTypeHelper; use PHPStan\Type\Traits\MaybeIterableTypeTrait; @@ -916,6 +917,11 @@ public function isObject(): TrinaryLogic return TrinaryLogic::createYes(); } + public function getClassStringType(): Type + { + return new GenericClassStringType($this); + } + public function isEnum(): TrinaryLogic { $classReflection = $this->getClassReflection(); diff --git a/src/Type/ObjectWithoutClassType.php b/src/Type/ObjectWithoutClassType.php index 9823dcaf80..f0c2ac3cdb 100644 --- a/src/Type/ObjectWithoutClassType.php +++ b/src/Type/ObjectWithoutClassType.php @@ -49,6 +49,11 @@ public function getObjectClassReflections(): array return []; } + public function getClassStringType(): Type + { + return new ClassStringType(); + } + public function accepts(Type $type, bool $strictTypes): AcceptsResult { if ($type instanceof CompoundType) { diff --git a/src/Type/Php/GetClassDynamicReturnTypeExtension.php b/src/Type/Php/GetClassDynamicReturnTypeExtension.php index e363214cb0..c79c2126f7 100644 --- a/src/Type/Php/GetClassDynamicReturnTypeExtension.php +++ b/src/Type/Php/GetClassDynamicReturnTypeExtension.php @@ -10,15 +10,8 @@ use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\DynamicFunctionReturnTypeExtension; -use PHPStan\Type\Enum\EnumCaseObjectType; -use PHPStan\Type\Generic\GenericClassStringType; -use PHPStan\Type\Generic\TemplateType; use PHPStan\Type\IntersectionType; -use PHPStan\Type\ObjectType; -use PHPStan\Type\ObjectWithoutClassType; -use PHPStan\Type\StaticType; use PHPStan\Type\Type; -use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypeTraverser; use PHPStan\Type\TypeUtils; use PHPStan\Type\UnionType; @@ -62,27 +55,12 @@ static function (Type $type, callable $traverse): Type { return $traverse($type); } - if ($type instanceof EnumCaseObjectType) { - return new GenericClassStringType(new ObjectType($type->getClassName())); - } - $isObject = $type->isObject(); if ($isObject->no()) { return new ConstantBooleanType(false); } - if ($type instanceof StaticType) { - $objectType = $type->getStaticObjectType(); - } else { - $objectType = TypeCombinator::intersect($type, new ObjectWithoutClassType()); - } - - if (!$objectType instanceof TemplateType && $objectType instanceof ObjectWithoutClassType) { - $classStringType = new ClassStringType(); - } else { - $classStringType = new GenericClassStringType($objectType); - } - + $classStringType = $type->getClassStringType(); if ($isObject->yes()) { return $classStringType; } diff --git a/src/Type/StaticType.php b/src/Type/StaticType.php index 21622b5b93..952f8c4f89 100644 --- a/src/Type/StaticType.php +++ b/src/Type/StaticType.php @@ -194,6 +194,11 @@ public function isObject(): TrinaryLogic return $this->getStaticObjectType()->isObject(); } + public function getClassStringType(): Type + { + return $this->getStaticObjectType()->getClassStringType(); + } + public function isEnum(): TrinaryLogic { return $this->getStaticObjectType()->isEnum(); diff --git a/src/Type/StrictMixedType.php b/src/Type/StrictMixedType.php index 71678b77a4..ce5a482892 100644 --- a/src/Type/StrictMixedType.php +++ b/src/Type/StrictMixedType.php @@ -110,6 +110,11 @@ public function isObject(): TrinaryLogic return TrinaryLogic::createNo(); } + public function getClassStringType(): Type + { + return new ErrorType(); + } + public function isEnum(): TrinaryLogic { return TrinaryLogic::createNo(); diff --git a/src/Type/Traits/LateResolvableTypeTrait.php b/src/Type/Traits/LateResolvableTypeTrait.php index d35ee72461..18092a0c62 100644 --- a/src/Type/Traits/LateResolvableTypeTrait.php +++ b/src/Type/Traits/LateResolvableTypeTrait.php @@ -88,6 +88,11 @@ public function isObject(): TrinaryLogic return $this->resolve()->isObject(); } + public function getClassStringType(): Type + { + return $this->resolve()->getClassStringType(); + } + public function isEnum(): TrinaryLogic { return $this->resolve()->isEnum(); diff --git a/src/Type/Traits/MaybeObjectTypeTrait.php b/src/Type/Traits/MaybeObjectTypeTrait.php index 71e4df3421..d6ff391374 100644 --- a/src/Type/Traits/MaybeObjectTypeTrait.php +++ b/src/Type/Traits/MaybeObjectTypeTrait.php @@ -14,6 +14,7 @@ use PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection; use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection; use PHPStan\TrinaryLogic; +use PHPStan\Type\ClassStringType; use PHPStan\Type\MixedType; use PHPStan\Type\Type; @@ -30,6 +31,11 @@ public function isObject(): TrinaryLogic return TrinaryLogic::createMaybe(); } + public function getClassStringType(): Type + { + return new ClassStringType(); + } + public function isEnum(): TrinaryLogic { return TrinaryLogic::createMaybe(); diff --git a/src/Type/Traits/NonObjectTypeTrait.php b/src/Type/Traits/NonObjectTypeTrait.php index 0d55341b46..35091c2e39 100644 --- a/src/Type/Traits/NonObjectTypeTrait.php +++ b/src/Type/Traits/NonObjectTypeTrait.php @@ -21,6 +21,11 @@ public function isObject(): TrinaryLogic return TrinaryLogic::createNo(); } + public function getClassStringType(): Type + { + return new ErrorType(); + } + public function isEnum(): TrinaryLogic { return TrinaryLogic::createNo(); diff --git a/src/Type/Type.php b/src/Type/Type.php index e9cbca0b7a..eaa9aed951 100644 --- a/src/Type/Type.php +++ b/src/Type/Type.php @@ -40,6 +40,8 @@ public function getObjectClassNames(): array; */ public function getObjectClassReflections(): array; + public function getClassStringType(): Type; + /** * Returns object type Foo for class-string and 'Foo' (if Foo is a valid class). */ diff --git a/src/Type/UnionType.php b/src/Type/UnionType.php index 178e72eeb9..9f82e04e7a 100644 --- a/src/Type/UnionType.php +++ b/src/Type/UnionType.php @@ -449,6 +449,11 @@ public function isObject(): TrinaryLogic return $this->unionResults(static fn (Type $type): TrinaryLogic => $type->isObject()); } + public function getClassStringType(): Type + { + return $this->unionTypes(static fn (Type $type): Type => $type->getClassStringType()); + } + public function isEnum(): TrinaryLogic { return $this->unionResults(static fn (Type $type): TrinaryLogic => $type->isEnum()); diff --git a/tests/PHPStan/Analyser/nsrt/bug-4890.php b/tests/PHPStan/Analyser/nsrt/bug-4890.php index 4c63fe7712..4480792eb2 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-4890.php +++ b/tests/PHPStan/Analyser/nsrt/bug-4890.php @@ -12,7 +12,7 @@ public function update(object $entity): void { assertType('class-string', get_class($entity)); assert(method_exists($entity, 'getId')); - assertType('class-string', get_class($entity)); + assertType('class-string', get_class($entity)); if ($entity instanceof Proxy) { assertType('class-string', get_class($entity)); @@ -29,7 +29,7 @@ public function updateProp(object $entity): void { assertType('class-string', get_class($entity)); assert(property_exists($entity, 'myProp')); - assertType('class-string', get_class($entity)); + assertType('class-string', get_class($entity)); if ($entity instanceof Proxy) { assertType('class-string', get_class($entity)); diff --git a/tests/PHPStan/Analyser/nsrt/generics.php b/tests/PHPStan/Analyser/nsrt/generics.php index 23f3a1e6c0..1968fab471 100644 --- a/tests/PHPStan/Analyser/nsrt/generics.php +++ b/tests/PHPStan/Analyser/nsrt/generics.php @@ -1316,7 +1316,7 @@ function arrayOfGenericClassStrings(array $a): void function getClassOnTemplateType($a, $b, $c, $d, $object, $mixed, $tObject) { assertType( - 'class-string|false', + 'class-string|false', get_class($a) ); assertType(