From 5490db8b6d1b530aea4d8a0bc4d683a0bc113dae Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 20 Dec 2022 12:53:49 +0100 Subject: [PATCH 1/5] Constant scalar types might accept general type from the same family --- src/Type/Traits/ConstantScalarTypeTrait.php | 2 +- tests/PHPStan/Levels/data/acceptTypes-5.json | 7 +------ tests/PHPStan/Levels/data/acceptTypes-7.json | 7 ++++++- 3 files changed, 8 insertions(+), 8 deletions(-) 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 +] From e466cfdaa7f8cfea6667a2dee6ec1c7239edf7f4 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 20 Dec 2022 13:25:13 +0100 Subject: [PATCH 2/5] Readability --- src/Type/ArrayType.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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; From e6dbea07ed410659423f17b4ecceaf28c1545a38 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 20 Dec 2022 13:45:57 +0100 Subject: [PATCH 3/5] Change IntersectionType::accepts() a bit --- src/Type/IntersectionType.php | 7 +++---- tests/PHPStan/Type/IntersectionTypeTest.php | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) 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/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(), ]; } From 8195a641c8136d0a9f8273d92676545fd8461a53 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 20 Dec 2022 15:30:55 +0100 Subject: [PATCH 4/5] Simplification again --- src/Rules/RuleLevelHelper.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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; From f72190c0dfaf3a98c3a2ca68f6528b12272ef4bd Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 20 Dec 2022 21:43:21 +0100 Subject: [PATCH 5/5] Fix build --- build/ignore-by-php-version.neon.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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'; }