diff --git a/build/ignore-by-php-version.neon.php b/build/ignore-by-php-version.neon.php index 1e60597046..cabdbb57b0 100644 --- a/build/ignore-by-php-version.neon.php +++ b/build/ignore-by-php-version.neon.php @@ -24,7 +24,7 @@ $includes[] = __DIR__ . '/enum-adapter-errors.neon'; } -if (PHP_VERSION_ID >= 70300 && PHP_VERSION_ID < 80000) { +if (PHP_VERSION_ID < 80000) { $includes[] = __DIR__ . '/more-enum-adapter-errors.neon'; } diff --git a/src/Rules/RuleLevelHelper.php b/src/Rules/RuleLevelHelper.php index 900a4b6eab..66dfc5c6a2 100644 --- a/src/Rules/RuleLevelHelper.php +++ b/src/Rules/RuleLevelHelper.php @@ -114,7 +114,10 @@ public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTyp } $accepts = $acceptingType->accepts($acceptedType, $strictTypes); - if (!$accepts->yes() && $acceptingType instanceof UnionType) { + if ($accepts->yes()) { + return true; + } + if ($acceptingType instanceof UnionType) { foreach ($acceptingType->getTypes() as $innerType) { if (self::accepts($innerType, $acceptedType, $strictTypes)) { return true; diff --git a/src/Type/ArrayType.php b/src/Type/ArrayType.php index 948270488c..3d2a5f307f 100644 --- a/src/Type/ArrayType.php +++ b/src/Type/ArrayType.php @@ -93,7 +93,9 @@ public function accepts(Type $type, bool $strictTypes): TrinaryLogic $itemType = $this->getItemType(); foreach ($type->getKeyTypes() as $i => $keyType) { $valueType = $type->getValueTypes()[$i]; - $result = $result->and($thisKeyType->accepts($keyType, $strictTypes))->and($itemType->accepts($valueType, $strictTypes)); + $acceptsKey = $thisKeyType->accepts($keyType, $strictTypes); + $acceptsValue = $itemType->accepts($valueType, $strictTypes); + $result = $result->and($acceptsKey)->and($acceptsValue); } return $result; diff --git a/src/Type/IntersectionType.php b/src/Type/IntersectionType.php index 2879dd00e9..cbc9dd2cd4 100644 --- a/src/Type/IntersectionType.php +++ b/src/Type/IntersectionType.php @@ -118,13 +118,12 @@ public function getConstantStrings(): array public function accepts(Type $otherType, bool $strictTypes): TrinaryLogic { + $results = []; foreach ($this->types as $type) { - if (!$type->accepts($otherType, $strictTypes)->yes()) { - return TrinaryLogic::createNo(); - } + $results[] = $type->accepts($otherType, $strictTypes); } - return TrinaryLogic::createYes(); + return TrinaryLogic::createYes()->and(...$results); } public function isSuperTypeOf(Type $otherType): TrinaryLogic diff --git a/src/Type/Traits/ConstantScalarTypeTrait.php b/src/Type/Traits/ConstantScalarTypeTrait.php index 4669a27219..7019cb4192 100644 --- a/src/Type/Traits/ConstantScalarTypeTrait.php +++ b/src/Type/Traits/ConstantScalarTypeTrait.php @@ -20,7 +20,7 @@ public function accepts(Type $type, bool $strictTypes): TrinaryLogic return $type->isAcceptedBy($this, $strictTypes); } - return TrinaryLogic::createNo(); + return parent::accepts($type, $strictTypes)->and(TrinaryLogic::createMaybe()); } public function isSuperTypeOf(Type $type): TrinaryLogic diff --git a/tests/PHPStan/Levels/data/acceptTypes-5.json b/tests/PHPStan/Levels/data/acceptTypes-5.json index acd06e6a48..bc719d23d1 100644 --- a/tests/PHPStan/Levels/data/acceptTypes-5.json +++ b/tests/PHPStan/Levels/data/acceptTypes-5.json @@ -174,11 +174,6 @@ "line": 707, "ignorable": true }, - { - "message": "Parameter #1 $numericString of method Levels\\AcceptTypes\\NumericStrings::doBar() expects numeric-string, string given.", - "line": 708, - "ignorable": true - }, { "message": "Parameter #1 $nonEmpty of method Levels\\AcceptTypes\\AcceptNonEmpty::doBar() expects non-empty-array, array{} given.", "line": 733, @@ -194,4 +189,4 @@ "line": 763, "ignorable": true } -] \ No newline at end of file +] diff --git a/tests/PHPStan/Levels/data/acceptTypes-7.json b/tests/PHPStan/Levels/data/acceptTypes-7.json index d9c0b8a45e..dc8f7d2459 100644 --- a/tests/PHPStan/Levels/data/acceptTypes-7.json +++ b/tests/PHPStan/Levels/data/acceptTypes-7.json @@ -154,9 +154,14 @@ "line": 692, "ignorable": true }, + { + "message": "Parameter #1 $numericString of method Levels\\AcceptTypes\\NumericStrings::doBar() expects numeric-string, string given.", + "line": 708, + "ignorable": true + }, { "message": "Parameter #2 $array of function implode expects array|null, array|int|string given.", "line": 756, "ignorable": true } -] \ No newline at end of file +] diff --git a/tests/PHPStan/Type/IntersectionTypeTest.php b/tests/PHPStan/Type/IntersectionTypeTest.php index c771c085fd..6fcb4d2d6a 100644 --- a/tests/PHPStan/Type/IntersectionTypeTest.php +++ b/tests/PHPStan/Type/IntersectionTypeTest.php @@ -42,7 +42,7 @@ public function dataAccepts(): Iterator yield [ $intersectionType, new IterableType(new MixedType(), new ObjectType('Item')), - TrinaryLogic::createNo(), + TrinaryLogic::createMaybe(), ]; yield [ @@ -57,7 +57,7 @@ public function dataAccepts(): Iterator yield [ TypeCombinator::intersect(new ArrayType(new MixedType(), new MixedType()), new CallableType()), new CallableType(), - TrinaryLogic::createNo(), + TrinaryLogic::createMaybe(), ]; }