diff --git a/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer/ReturnedNodesReturnTypeInfererTypeInferer.php b/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer/ReturnedNodesReturnTypeInfererTypeInferer.php index ea49fc7c43a..f5f6875c5b8 100644 --- a/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer/ReturnedNodesReturnTypeInfererTypeInferer.php +++ b/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer/ReturnedNodesReturnTypeInfererTypeInferer.php @@ -84,7 +84,7 @@ final class ReturnedNodesReturnTypeInfererTypeInferer if ($this->silentVoidResolver->hasSilentVoid($functionLike)) { $types[] = new VoidType(); } - return $this->typeFactory->createMixedPassedOrUnionType($types); + return $this->typeFactory->createMixedPassedOrUnionTypeAndKeepConstant($types); } /** * @return Return_[] diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index b2bbe317738..f1789e137b7 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -19,12 +19,12 @@ final class VersionResolver * @api * @var string */ - public const PACKAGE_VERSION = '5c0397910fbd9735c375c4632ec116ebe8609f25'; + public const PACKAGE_VERSION = '09c077e25801da58834be284a792c3987ea806ef'; /** * @api * @var string */ - public const RELEASE_DATE = '2024-01-02 21:36:20'; + public const RELEASE_DATE = '2024-01-03 14:49:58'; /** * @var int */ diff --git a/src/NodeTypeResolver/PHPStan/Type/TypeFactory.php b/src/NodeTypeResolver/PHPStan/Type/TypeFactory.php index d58b7b64907..b2137b85382 100644 --- a/src/NodeTypeResolver/PHPStan/Type/TypeFactory.php +++ b/src/NodeTypeResolver/PHPStan/Type/TypeFactory.php @@ -59,11 +59,11 @@ final class TypeFactory $constantTypeHashes = []; $uniqueTypes = []; $totalTypes = \count($types); + $hasFalse = \false; + $hasTrue = \false; foreach ($types as $type) { - if ($totalTypes > 1 && $type instanceof ObjectWithoutClassTypeWithParentTypes) { - $parents = $type->getParentTypes(); - $type = new ObjectType($parents[0]->getClassName()); - } + $type = $this->normalizeObjectType($totalTypes, $type); + $type = $this->normalizeBooleanType($hasFalse, $hasTrue, $type); $removedConstantType = $this->removeValueFromConstantType($type); $removedConstantTypeHash = $this->typeHasher->createTypeHash($removedConstantType); if ($keepConstant && $type !== $removedConstantType) { @@ -83,6 +83,29 @@ final class TypeFactory // re-index return \array_values($uniqueTypes); } + private function normalizeObjectType(int $totalTypes, Type $type) : Type + { + if ($totalTypes > 1 && $type instanceof ObjectWithoutClassTypeWithParentTypes) { + $parents = $type->getParentTypes(); + return new ObjectType($parents[0]->getClassName()); + } + return $type; + } + private function normalizeBooleanType(bool &$hasFalse, bool &$hasTrue, Type $type) : Type + { + if ($type instanceof ConstantBooleanType) { + if ($type->getValue()) { + $hasTrue = \true; + } + if ($type->getValue() === \false) { + $hasFalse = \true; + } + } + if ($hasFalse && $hasTrue && $type instanceof ConstantBooleanType) { + return new BooleanType(); + } + return $type; + } /** * @param Type[] $types * @return Type[] diff --git a/src/NodeTypeResolver/PHPStan/TypeHasher.php b/src/NodeTypeResolver/PHPStan/TypeHasher.php index a6e3419c0a2..1861386a86c 100644 --- a/src/NodeTypeResolver/PHPStan/TypeHasher.php +++ b/src/NodeTypeResolver/PHPStan/TypeHasher.php @@ -39,7 +39,7 @@ final class TypeHasher return $this->resolveUniqueTypeWithClassNameHash($type); } if ($type instanceof ConstantType) { - return \get_class($type) . $type->getValue(); + return \get_class($type); } if ($type instanceof UnionType) { return $this->createUnionTypeHash($type);