From dc5d8f4d3eef18b1d80b8ffb3a1adfe8de6d7268 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 18 Oct 2024 09:20:02 +0200 Subject: [PATCH] Decorate reasons when comparing ConstantArrayType --- phpstan-baseline.neon | 13 +++++++++++++ src/Analyser/RicherScopeGetTypeHelper.php | 4 ++++ src/Type/Constant/ConstantArrayType.php | 2 +- .../StrictComparisonOfDifferentTypesRuleTest.php | 5 +++++ .../Rules/Comparison/data/strict-comparison.php | 14 ++++++++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 197663fec6..73144c4ac1 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -66,6 +66,11 @@ parameters: count: 1 path: src/Analyser/NodeScopeResolver.php + - + message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantBooleanType is error\\-prone and deprecated\\. Use Type\\:\\:isTrue\\(\\) or Type\\:\\:isFalse\\(\\) instead\\.$#" + count: 1 + path: src/Analyser/RicherScopeGetTypeHelper.php + - message: "#^Doing instanceof PHPStan\\\\Type\\\\ConstantScalarType is error\\-prone and deprecated\\. Use Type\\:\\:isConstantScalarValue\\(\\) or Type\\:\\:getConstantScalarTypes\\(\\) or Type\\:\\:getConstantScalarValues\\(\\) instead\\.$#" count: 2 @@ -487,6 +492,14 @@ parameters: count: 2 path: src/Rules/Comparison/NumberComparisonOperatorsConstantConditionRule.php + - + message: """ + #^Call to deprecated method doNotTreatPhpDocTypesAsCertain\\(\\) of interface PHPStan\\\\Analyser\\\\Scope\\: + Use getNativeType\\(\\)$# + """ + count: 2 + path: src/Rules/Comparison/StrictComparisonOfDifferentTypesRule.php + - message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantBooleanType is error\\-prone and deprecated\\. Use Type\\:\\:isTrue\\(\\) or Type\\:\\:isFalse\\(\\) instead\\.$#" count: 2 diff --git a/src/Analyser/RicherScopeGetTypeHelper.php b/src/Analyser/RicherScopeGetTypeHelper.php index e60612f820..ba7c6c618a 100644 --- a/src/Analyser/RicherScopeGetTypeHelper.php +++ b/src/Analyser/RicherScopeGetTypeHelper.php @@ -36,6 +36,10 @@ public function getIdenticalResult(Scope $scope, Identical $expr): TypeResult $leftType = $scope->getType($expr->left); $rightType = $scope->getType($expr->right); + if (!$scope instanceof MutatingScope) { + return $this->initializerExprTypeResolver->resolveIdenticalType($leftType, $rightType); + } + if ( ( $expr->left instanceof Node\Expr\PropertyFetch diff --git a/src/Type/Constant/ConstantArrayType.php b/src/Type/Constant/ConstantArrayType.php index 74786c7e89..1b770d6889 100644 --- a/src/Type/Constant/ConstantArrayType.php +++ b/src/Type/Constant/ConstantArrayType.php @@ -390,7 +390,7 @@ public function isSuperTypeOfWithReason(Type $type): IsSuperTypeOfResult $isValueSuperType = $this->valueTypes[$i]->isSuperTypeOfWithReason($type->getOffsetValueType($keyType)); if ($isValueSuperType->no()) { - return $isValueSuperType; + return $isValueSuperType->decorateReasons(static fn (string $reason) => sprintf('Offset %s: %s', $keyType->describe(VerbosityLevel::value()), $reason)); } $results[] = $isValueSuperType; } diff --git a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php index 96712b66b9..01157d82e1 100644 --- a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php @@ -289,6 +289,11 @@ public function testStrictComparison(): void 1034, 'Type null has already been eliminated from mixed.', ], + [ + 'Strict comparison using !== between array{1, mixed, 3} and array{int, null, int} will always evaluate to true.', + 1048, + 'Offset 1: Type null has already been eliminated from mixed.', + ], ], ); } diff --git a/tests/PHPStan/Rules/Comparison/data/strict-comparison.php b/tests/PHPStan/Rules/Comparison/data/strict-comparison.php index b6389bd5ee..70882c4ca4 100644 --- a/tests/PHPStan/Rules/Comparison/data/strict-comparison.php +++ b/tests/PHPStan/Rules/Comparison/data/strict-comparison.php @@ -1036,4 +1036,18 @@ public function doFoo($m): void } } + public function doBar($m, int $i, int $j): void + { + if ($m === null) { + return; + } + + $a = [1, $m, 3]; + $b = [$i, null, $j]; + + if ($a !== $b) { + + } + } + }