|
18 | 18 | use PHPStan\Type\Constant\ConstantFloatType; |
19 | 19 | use PHPStan\Type\Constant\ConstantIntegerType; |
20 | 20 | use PHPStan\Type\Constant\ConstantStringType; |
21 | | -use PHPStan\Type\Enum\EnumCaseObjectType; |
22 | 21 | use PHPStan\Type\Generic\GenericClassStringType; |
23 | 22 | use PHPStan\Type\Generic\TemplateArrayType; |
24 | 23 | use PHPStan\Type\Generic\TemplateBenevolentUnionType; |
@@ -540,7 +539,7 @@ private static function unionWithSubtractedType( |
540 | 539 | return $type; |
541 | 540 | } |
542 | 541 |
|
543 | | - if ($type instanceof SubtractableType && ! $type instanceof EnumCaseObjectType) { |
| 542 | + if ($type instanceof SubtractableType) { |
544 | 543 | $subtractedType = $type->getSubtractedType() === null |
545 | 544 | ? $subtractedType |
546 | 545 | : self::union($type->getSubtractedType(), $subtractedType); |
@@ -596,17 +595,31 @@ private static function intersectWithSubtractedType( |
596 | 595 | } |
597 | 596 |
|
598 | 597 | $subtractedType = self::union(...$subtractedTypes); |
599 | | - } elseif ($b instanceof SubtractableType && ! $b instanceof EnumCaseObjectType) { |
600 | | - $subtractedType = $b->getSubtractedType(); |
601 | | - if ($subtractedType === null) { |
602 | | - return $a->getTypeWithoutSubtractedType(); |
603 | | - } |
604 | 598 | } else { |
605 | | - $subtractedTypeTmp = self::intersect($a->getTypeWithoutSubtractedType(), $a->getSubtractedType()); |
606 | | - if ($b->isSuperTypeOf($subtractedTypeTmp)->yes()) { |
607 | | - return $a->getTypeWithoutSubtractedType(); |
| 599 | + $isBAlreadySubtracted = $a->getSubtractedType()->isSuperTypeOf($b); |
| 600 | + |
| 601 | + if ($isBAlreadySubtracted->no()) { |
| 602 | + return $a; |
| 603 | + } elseif ($isBAlreadySubtracted->yes()) { |
| 604 | + $subtractedType = self::remove($a->getSubtractedType(), $b); |
| 605 | + |
| 606 | + if ($subtractedType instanceof NeverType) { |
| 607 | + $subtractedType = null; |
| 608 | + } |
| 609 | + |
| 610 | + return $a->changeSubtractedType($subtractedType); |
| 611 | + } elseif ($b instanceof SubtractableType) { |
| 612 | + $subtractedType = $b->getSubtractedType(); |
| 613 | + if ($subtractedType === null) { |
| 614 | + return $a->getTypeWithoutSubtractedType(); |
| 615 | + } |
| 616 | + } else { |
| 617 | + $subtractedTypeTmp = self::intersect($a->getTypeWithoutSubtractedType(), $a->getSubtractedType()); |
| 618 | + if ($b->isSuperTypeOf($subtractedTypeTmp)->yes()) { |
| 619 | + return $a->getTypeWithoutSubtractedType(); |
| 620 | + } |
| 621 | + $subtractedType = new MixedType(false, $b); |
608 | 622 | } |
609 | | - $subtractedType = new MixedType(false, $b); |
610 | 623 | } |
611 | 624 |
|
612 | 625 | $subtractedType = self::intersect( |
|
0 commit comments