diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d1a31cf0bf..3417336772 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1656,7 +1656,7 @@ parameters: - rawMessage: 'Doing instanceof PHPStan\Type\Constant\ConstantArrayType is error-prone and deprecated. Use Type::getConstantArrays() instead.' identifier: phpstanApi.instanceofType - count: 21 + count: 22 path: src/Type/TypeCombinator.php - diff --git a/src/Type/TypeCombinator.php b/src/Type/TypeCombinator.php index 3413ec6e8d..14cf2a2fe9 100644 --- a/src/Type/TypeCombinator.php +++ b/src/Type/TypeCombinator.php @@ -1609,9 +1609,14 @@ public static function intersect(Type ...$types): Type $newTypes = []; $hasOffsetValueTypeCount = 0; $typesCount = count($types); + $typesNeedSorting = false; for ($i = 0; $i < $typesCount; $i++) { $type = $types[$i]; + if ($type instanceof SubtractableType || $type instanceof ConstantArrayType) { + $typesNeedSorting = true; + } + if ($type instanceof IntersectionType && !$type instanceof TemplateType) { // transform A & (B & C) to A & B & C array_splice($types, $i--, 1, $type->getTypes()); @@ -1629,24 +1634,26 @@ public static function intersect(Type ...$types): Type $typesCount = count($types); } - usort($types, static function (Type $a, Type $b): int { - // move subtractables with subtracts before those without to avoid losing them in the union logic - if ($a instanceof SubtractableType && $a->getSubtractedType() !== null) { - return -1; - } - if ($b instanceof SubtractableType && $b->getSubtractedType() !== null) { - return 1; - } + if ($typesNeedSorting) { + usort($types, static function (Type $a, Type $b): int { + // move subtractables with subtracts before those without to avoid losing them in the union logic + if ($a instanceof SubtractableType && $a->getSubtractedType() !== null) { + return -1; + } + if ($b instanceof SubtractableType && $b->getSubtractedType() !== null) { + return 1; + } - if ($a instanceof ConstantArrayType && !$b instanceof ConstantArrayType) { - return -1; - } - if ($b instanceof ConstantArrayType && !$a instanceof ConstantArrayType) { - return 1; - } + if ($a instanceof ConstantArrayType && !$b instanceof ConstantArrayType) { + return -1; + } + if ($b instanceof ConstantArrayType && !$a instanceof ConstantArrayType) { + return 1; + } - return 0; - }); + return 0; + }); + } // transform IntegerType & ConstantIntegerType to ConstantIntegerType // transform Child & Parent to Child