From 07d3ca2e42e5ca701cc4482af8dab7561886e4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tinjo=20Sch=C3=B6ni?= <32767367+tscni@users.noreply.github.com> Date: Sat, 17 Aug 2024 02:01:38 +0200 Subject: [PATCH 1/3] Fix ConstantArrayType not accepting NeverType --- src/Type/Constant/ConstantArrayType.php | 4 +++ .../CallToFunctionParametersRuleTest.php | 7 +---- .../Generators/YieldFromTypeRuleTest.php | 5 ++++ .../Rules/Generators/data/bug-11517.php | 30 +++++++++++++++++++ .../Type/Constant/ConstantArrayTypeTest.php | 13 ++++++++ 5 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 tests/PHPStan/Rules/Generators/data/bug-11517.php diff --git a/src/Type/Constant/ConstantArrayType.php b/src/Type/Constant/ConstantArrayType.php index 9afb19daf5..503dc85e7c 100644 --- a/src/Type/Constant/ConstantArrayType.php +++ b/src/Type/Constant/ConstantArrayType.php @@ -300,6 +300,10 @@ public function acceptsWithReason(Type $type, bool $strictTypes): AcceptsResult return $type->isAcceptedWithReasonBy($this, $strictTypes); } + if ($type instanceof NeverType) { + return $type->isAcceptedWithReasonBy($this, $strictTypes); + } + if ($type instanceof self && count($this->keyTypes) === 0) { return AcceptsResult::createFromBoolean(count($type->keyTypes) === 0); } diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php index b9368eef46..3ddad85c09 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php @@ -1126,12 +1126,7 @@ public function testBug7211(): void public function testBug5474(): void { - $this->analyse([__DIR__ . '/../Comparison/data/bug-5474.php'], [ - [ - 'Parameter #1 $data of function Bug5474\testData expects array{test: int}, *NEVER* given.', - 26, - ], - ]); + $this->analyse([__DIR__ . '/../Comparison/data/bug-5474.php'], []); } public function testBug6261(): void diff --git a/tests/PHPStan/Rules/Generators/YieldFromTypeRuleTest.php b/tests/PHPStan/Rules/Generators/YieldFromTypeRuleTest.php index deada99fb1..681d9abab1 100644 --- a/tests/PHPStan/Rules/Generators/YieldFromTypeRuleTest.php +++ b/tests/PHPStan/Rules/Generators/YieldFromTypeRuleTest.php @@ -48,4 +48,9 @@ public function testRule(): void ]); } + public function testBug11517(): void + { + $this->analyse([__DIR__ . '/data/bug-11517.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Generators/data/bug-11517.php b/tests/PHPStan/Rules/Generators/data/bug-11517.php new file mode 100644 index 0000000000..56b64a5bd0 --- /dev/null +++ b/tests/PHPStan/Rules/Generators/data/bug-11517.php @@ -0,0 +1,30 @@ + + */ + public function bug(): iterable + { + yield from []; + } + + /** + * @return iterable + */ + public function fine(): iterable + { + yield from []; + } + + /** + * @return iterable + */ + public function finetoo(): iterable + { + yield from []; + } +} diff --git a/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php b/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php index 990b2b54ae..45fa8ba76f 100644 --- a/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php +++ b/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php @@ -14,6 +14,7 @@ use PHPStan\Type\IntegerType; use PHPStan\Type\IterableType; use PHPStan\Type\MixedType; +use PHPStan\Type\NeverType; use PHPStan\Type\ObjectType; use PHPStan\Type\StringType; use PHPStan\Type\Type; @@ -345,6 +346,18 @@ public function dataAccepts(): iterable ]), TrinaryLogic::createNo(), ]; + + yield [ + new ConstantArrayType([], []), + new NeverType(), + TrinaryLogic::createYes(), + ]; + + yield [ + new ConstantArrayType([new ConstantIntegerType(1)], [new ConstantIntegerType(2)]), + new NeverType(), + TrinaryLogic::createYes(), + ]; } /** From e5c9b0433b0d6060fbd17a9c1d7bbf1d5f49ed58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tinjo=20Sch=C3=B6ni?= <32767367+tscni@users.noreply.github.com> Date: Wed, 21 Aug 2024 21:25:53 +0200 Subject: [PATCH 2/3] Use generic CompoundType based check, except for intersections --- src/Type/Constant/ConstantArrayType.php | 7 +-- .../Type/Constant/ConstantArrayTypeTest.php | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/Type/Constant/ConstantArrayType.php b/src/Type/Constant/ConstantArrayType.php index 503dc85e7c..3853794348 100644 --- a/src/Type/Constant/ConstantArrayType.php +++ b/src/Type/Constant/ConstantArrayType.php @@ -33,7 +33,6 @@ use PHPStan\Type\ConstantType; use PHPStan\Type\ErrorType; use PHPStan\Type\GeneralizePrecision; -use PHPStan\Type\Generic\TemplateMixedType; use PHPStan\Type\Generic\TemplateTypeMap; use PHPStan\Type\Generic\TemplateTypeVariance; use PHPStan\Type\IntegerRangeType; @@ -296,11 +295,7 @@ public function accepts(Type $type, bool $strictTypes): TrinaryLogic public function acceptsWithReason(Type $type, bool $strictTypes): AcceptsResult { - if ($type instanceof MixedType && !$type instanceof TemplateMixedType) { - return $type->isAcceptedWithReasonBy($this, $strictTypes); - } - - if ($type instanceof NeverType) { + if ($type instanceof CompoundType && !$type instanceof IntersectionType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } diff --git a/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php b/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php index 45fa8ba76f..727fd65d01 100644 --- a/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php +++ b/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php @@ -5,6 +5,8 @@ use Closure; use PHPStan\Testing\PHPStanTestCase; use PHPStan\TrinaryLogic; +use PHPStan\Type\Accessory\HasOffsetType; +use PHPStan\Type\Accessory\HasOffsetValueType; use PHPStan\Type\ArrayType; use PHPStan\Type\CallableType; use PHPStan\Type\Generic\GenericClassStringType; @@ -12,6 +14,7 @@ use PHPStan\Type\Generic\TemplateTypeScope; use PHPStan\Type\Generic\TemplateTypeVariance; use PHPStan\Type\IntegerType; +use PHPStan\Type\IntersectionType; use PHPStan\Type\IterableType; use PHPStan\Type\MixedType; use PHPStan\Type\NeverType; @@ -358,6 +361,51 @@ public function dataAccepts(): iterable new NeverType(), TrinaryLogic::createYes(), ]; + + yield [ + new ConstantArrayType([new ConstantStringType('test')], [new MixedType()]), + new IntersectionType([ + new ArrayType(new MixedType(), new MixedType()), + new HasOffsetType(new ConstantStringType('test')), + ]), + TrinaryLogic::createYes(), + ]; + + yield [ + new ConstantArrayType([new ConstantStringType('test')], [new StringType()]), + new IntersectionType([ + new ArrayType(new MixedType(), new MixedType()), + new HasOffsetValueType(new ConstantStringType('test'), new StringType()), + ]), + TrinaryLogic::createYes(), + ]; + + yield [ + new ConstantArrayType([new ConstantStringType('test')], [new MixedType()]), + new UnionType([ + new ArrayType(new MixedType(), new MixedType()), + new HasOffsetType(new ConstantStringType('test')), + ]), + TrinaryLogic::createMaybe(), + ]; + + yield [ + new ConstantArrayType([new ConstantStringType('test')], [new StringType()]), + new UnionType([ + new ArrayType(new MixedType(), new MixedType()), + new HasOffsetValueType(new ConstantStringType('test'), new StringType()), + ]), + TrinaryLogic::createMaybe(), + ]; + + yield [ + new ConstantArrayType([new ConstantStringType('test')], [new MixedType()]), + new IntersectionType([ + new UnionType([new ArrayType(new MixedType(), new MixedType()), new IterableType(new MixedType(), new MixedType())]), + new HasOffsetType(new ConstantStringType('test')), + ]), + TrinaryLogic::createMaybe(), + ]; } /** From f4366e138788af430137273303324ee7102b891a Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 22 Aug 2024 09:22:26 +0200 Subject: [PATCH 3/3] Update baseline --- phpstan-baseline.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ffccb8bd22..cdf3372afc 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -848,7 +848,7 @@ parameters: - message: "#^Doing instanceof PHPStan\\\\Type\\\\IntersectionType is error\\-prone and deprecated\\.$#" - count: 1 + count: 2 path: src/Type/Constant/ConstantArrayType.php -