diff --git a/UPGRADING.md b/UPGRADING.md index db47c80157a..5656531a48b 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,126 +1,127 @@ # Upgrading from Psalm 4 to Psalm 5 ## Changed - - [BC] The parameter `$php_version` of `Psalm\Type\Atomic::create()` renamed - to `$analysis_php_version_id` and changed from `array|null` to `int|null`. - Previously it accepted PHP version as `array{major_version, minor_version}` - while now it accepts version ID, similar to how [`PHP_VERSION_ID` is - calculated](https://www.php.net/manual/en/reserved.constants.php#constant.php-version-id). +- [BC] TPositiveInt has been removed and replaced by TIntRange - - [BC] The parameter `$php_version` of `Psalm\Type::parseString()` renamed to - `$analysis_php_version_id` and changed from `array|null` to `int|null`. - Previously it accepted PHP version as `array{major_version, minor_version}` - while now it accepts version ID. +- [BC] The parameter `$php_version` of `Psalm\Type\Atomic::create()` renamed + to `$analysis_php_version_id` and changed from `array|null` to `int|null`. + Previously it accepted PHP version as `array{major_version, minor_version}` + while now it accepts version ID, similar to how [`PHP_VERSION_ID` is + calculated](https://www.php.net/manual/en/reserved.constants.php#constant.php-version-id). - - [BC] Parameter 0 of `canBeFullyExpressedInPhp()` of the classes listed below - changed name from `php_major_version` to `analysis_php_version_id`. - Previously it accepted major PHP version as int (e.g. `7`), while now it - accepts version ID. Classes affected: - - `Psalm\Type\Atomic` - - `Psalm\Type\Atomic\Scalar` - - `Psalm\Type\Atomic\TArray` - - `Psalm\Type\Atomic\TArrayKey` - - `Psalm\Type\Atomic\TCallable` - - `Psalm\Type\Atomic\TCallableObject` - - `Psalm\Type\Atomic\TCallableString` - - `Psalm\Type\Atomic\TClassConstant` - - `Psalm\Type\Atomic\TClassString` - - `Psalm\Type\Atomic\TClassStringMap` - - `Psalm\Type\Atomic\TClosedResource` - - `Psalm\Type\Atomic\TClosure` - - `Psalm\Type\Atomic\TConditional` - - `Psalm\Type\Atomic\TDependentGetClass` - - `Psalm\Type\Atomic\TDependentGetDebugType` - - `Psalm\Type\Atomic\TDependentGetType` - - `Psalm\Type\Atomic\TDependentListKey` - - `Psalm\Type\Atomic\TEnumCase` - - `Psalm\Type\Atomic\TFalse` - - `Psalm\Type\Atomic\TGenericObject` - - `Psalm\Type\Atomic\TIntMask` - - `Psalm\Type\Atomic\TIntMaskOf` - - `Psalm\Type\Atomic\TIntRange` - - `Psalm\Type\Atomic\TIterable` - - `Psalm\Type\Atomic\TKeyedArray` - - `Psalm\Type\Atomic\TKeyOfClassConstant` - - `Psalm\Type\Atomic\TList` - - `Psalm\Type\Atomic\TLiteralClassString` - - `Psalm\Type\Atomic\TLowercaseString` - - `Psalm\Type\Atomic\TMixed` - - `Psalm\Type\Atomic\TNamedObject` - - `Psalm\Type\Atomic\TNever` - - `Psalm\Type\Atomic\TNonEmptyLowercaseString` - - `Psalm\Type\Atomic\TNonspecificLiteralInt` - - `Psalm\Type\Atomic\TNonspecificLiteralString` - - `Psalm\Type\Atomic\TNull` - - `Psalm\Type\Atomic\TNumeric` - - `Psalm\Type\Atomic\TNumericString` - - `Psalm\Type\Atomic\TObject` - - `Psalm\Type\Atomic\TObjectWithProperties` - - `Psalm\Type\Atomic\TPositiveInt` - - `Psalm\Type\Atomic\TResource` - - `Psalm\Type\Atomic\TScalar` - - `Psalm\Type\Atomic\TTemplateIndexedAccess` - - `Psalm\Type\Atomic\TTemplateParam` - - `Psalm\Type\Atomic\TTraitString` - - `Psalm\Type\Atomic\TTrue` - - `Psalm\Type\Atomic\TTypeAlias` - - `Psalm\Type\Atomic\TValueOfClassConstant` - - `Psalm\Type\Atomic\TVoid` - - `Psalm\Type\Union` +- [BC] The parameter `$php_version` of `Psalm\Type::parseString()` renamed to + `$analysis_php_version_id` and changed from `array|null` to `int|null`. + Previously it accepted PHP version as `array{major_version, minor_version}` + while now it accepts version ID. - - [BC] Parameter 3 of `toPhpString()` of methods listed below changed name - from `php_major_version` to `analysis_php_version_id`. Previously it - accepted major PHP version as int (e.g. `7`), while now it accepts version - ID. Classes affected: - - `Psalm\Type\Atomic` - - `Psalm\Type\Atomic\CallableTrait` - - `Psalm\Type\Atomic\TAnonymousClassInstance` - - `Psalm\Type\Atomic\TArray` - - `Psalm\Type\Atomic\TArrayKey` - - `Psalm\Type\Atomic\TBool` - - `Psalm\Type\Atomic\TCallable` - - `Psalm\Type\Atomic\TCallableObject` - - `Psalm\Type\Atomic\TClassConstant` - - `Psalm\Type\Atomic\TClassString` - - `Psalm\Type\Atomic\TClassStringMap` - - `Psalm\Type\Atomic\TClosedResource` - - `Psalm\Type\Atomic\TConditional` - - `Psalm\Type\Atomic\TEmpty` - - `Psalm\Type\Atomic\TEnumCase` - - `Psalm\Type\Atomic\TFloat` - - `Psalm\Type\Atomic\TGenericObject` - - `Psalm\Type\Atomic\TInt` - - `Psalm\Type\Atomic\TIterable` - - `Psalm\Type\Atomic\TKeyedArray` - - `Psalm\Type\Atomic\TKeyOfClassConstant` - - `Psalm\Type\Atomic\TList` - - `Psalm\Type\Atomic\TLiteralClassString` - - `Psalm\Type\Atomic\TMixed` - - `Psalm\Type\Atomic\TNamedObject` - - `Psalm\Type\Atomic\TNever` - - `Psalm\Type\Atomic\TNull` - - `Psalm\Type\Atomic\TNumeric` - - `Psalm\Type\Atomic\TObject` - - `Psalm\Type\Atomic\TObjectWithProperties` - - `Psalm\Type\Atomic\TResource` - - `Psalm\Type\Atomic\TScalar` - - `Psalm\Type\Atomic\TString` - - `Psalm\Type\Atomic\TTemplateIndexedAccess` - - `Psalm\Type\Atomic\TTemplateParam` - - `Psalm\Type\Atomic\TTraitString` - - `Psalm\Type\Atomic\TTypeAlias` - - `Psalm\Type\Atomic\TValueOfClassConstant` - - `Psalm\Type\Atomic\TVoid` - - `Psalm\Type\Union` - - While not a BC break per se, all classes / interfaces / traits / enums under - `Psalm\Internal` namespace are now marked `@internal`. - - [BC] Parameter 1 of `Psalm\Type\Atomic\TNamedObject::__construct()` changed name from `was_static` to `is_static` - - [BC] Parameter 1 of `Psalm\Type\Atomic\TAnonymousClassInstance::__construct()` changed name from `was_static` to `is_static` - - [BC] Parameter 5 of `Psalm\Type::getStringFromFQCLN()` changed name from `was_static` to `is_static` - - [BC] Property `Psalm\Type\Atomic\TNamedObject::$was_static` was renamed to `$is_static` - - [BC] Method `Psalm\Type\Union::isFormerStaticObject()` was renamed to `isStaticObject()` - - [BC] Method `Psalm\Type\Union::hasFormerStaticObject()` was renamed to `hasStaticObject()` - - [BC] Function assertions (from `@psalm-assert Foo $bar`) have been converted from strings to specific `Assertion` objects. - - [BC] Property `Psalm\Storage\ClassLikeStorage::$invalid_dependencies` changed from `array` to `array`. +- [BC] Parameter 0 of `canBeFullyExpressedInPhp()` of the classes listed below + changed name from `php_major_version` to `analysis_php_version_id`. + Previously it accepted major PHP version as int (e.g. `7`), while now it + accepts version ID. Classes affected: + - `Psalm\Type\Atomic` + - `Psalm\Type\Atomic\Scalar` + - `Psalm\Type\Atomic\TArray` + - `Psalm\Type\Atomic\TArrayKey` + - `Psalm\Type\Atomic\TCallable` + - `Psalm\Type\Atomic\TCallableObject` + - `Psalm\Type\Atomic\TCallableString` + - `Psalm\Type\Atomic\TClassConstant` + - `Psalm\Type\Atomic\TClassString` + - `Psalm\Type\Atomic\TClassStringMap` + - `Psalm\Type\Atomic\TClosedResource` + - `Psalm\Type\Atomic\TClosure` + - `Psalm\Type\Atomic\TConditional` + - `Psalm\Type\Atomic\TDependentGetClass` + - `Psalm\Type\Atomic\TDependentGetDebugType` + - `Psalm\Type\Atomic\TDependentGetType` + - `Psalm\Type\Atomic\TDependentListKey` + - `Psalm\Type\Atomic\TEnumCase` + - `Psalm\Type\Atomic\TFalse` + - `Psalm\Type\Atomic\TGenericObject` + - `Psalm\Type\Atomic\TIntMask` + - `Psalm\Type\Atomic\TIntMaskOf` + - `Psalm\Type\Atomic\TIntRange` + - `Psalm\Type\Atomic\TIterable` + - `Psalm\Type\Atomic\TKeyedArray` + - `Psalm\Type\Atomic\TKeyOfClassConstant` + - `Psalm\Type\Atomic\TList` + - `Psalm\Type\Atomic\TLiteralClassString` + - `Psalm\Type\Atomic\TLowercaseString` + - `Psalm\Type\Atomic\TMixed` + - `Psalm\Type\Atomic\TNamedObject` + - `Psalm\Type\Atomic\TNever` + - `Psalm\Type\Atomic\TNonEmptyLowercaseString` + - `Psalm\Type\Atomic\TNonspecificLiteralInt` + - `Psalm\Type\Atomic\TNonspecificLiteralString` + - `Psalm\Type\Atomic\TNull` + - `Psalm\Type\Atomic\TNumeric` + - `Psalm\Type\Atomic\TNumericString` + - `Psalm\Type\Atomic\TObject` + - `Psalm\Type\Atomic\TObjectWithProperties` + - `Psalm\Type\Atomic\TResource` + - `Psalm\Type\Atomic\TScalar` + - `Psalm\Type\Atomic\TTemplateIndexedAccess` + - `Psalm\Type\Atomic\TTemplateParam` + - `Psalm\Type\Atomic\TTraitString` + - `Psalm\Type\Atomic\TTrue` + - `Psalm\Type\Atomic\TTypeAlias` + - `Psalm\Type\Atomic\TValueOfClassConstant` + - `Psalm\Type\Atomic\TVoid` + - `Psalm\Type\Union` + +- [BC] Parameter 3 of `toPhpString()` of methods listed below changed name + from `php_major_version` to `analysis_php_version_id`. Previously it + accepted major PHP version as int (e.g. `7`), while now it accepts version + ID. Classes affected: + - `Psalm\Type\Atomic` + - `Psalm\Type\Atomic\CallableTrait` + - `Psalm\Type\Atomic\TAnonymousClassInstance` + - `Psalm\Type\Atomic\TArray` + - `Psalm\Type\Atomic\TArrayKey` + - `Psalm\Type\Atomic\TBool` + - `Psalm\Type\Atomic\TCallable` + - `Psalm\Type\Atomic\TCallableObject` + - `Psalm\Type\Atomic\TClassConstant` + - `Psalm\Type\Atomic\TClassString` + - `Psalm\Type\Atomic\TClassStringMap` + - `Psalm\Type\Atomic\TClosedResource` + - `Psalm\Type\Atomic\TConditional` + - `Psalm\Type\Atomic\TEmpty` + - `Psalm\Type\Atomic\TEnumCase` + - `Psalm\Type\Atomic\TFloat` + - `Psalm\Type\Atomic\TGenericObject` + - `Psalm\Type\Atomic\TInt` + - `Psalm\Type\Atomic\TIterable` + - `Psalm\Type\Atomic\TKeyedArray` + - `Psalm\Type\Atomic\TKeyOfClassConstant` + - `Psalm\Type\Atomic\TList` + - `Psalm\Type\Atomic\TLiteralClassString` + - `Psalm\Type\Atomic\TMixed` + - `Psalm\Type\Atomic\TNamedObject` + - `Psalm\Type\Atomic\TNever` + - `Psalm\Type\Atomic\TNull` + - `Psalm\Type\Atomic\TNumeric` + - `Psalm\Type\Atomic\TObject` + - `Psalm\Type\Atomic\TObjectWithProperties` + - `Psalm\Type\Atomic\TResource` + - `Psalm\Type\Atomic\TScalar` + - `Psalm\Type\Atomic\TString` + - `Psalm\Type\Atomic\TTemplateIndexedAccess` + - `Psalm\Type\Atomic\TTemplateParam` + - `Psalm\Type\Atomic\TTraitString` + - `Psalm\Type\Atomic\TTypeAlias` + - `Psalm\Type\Atomic\TValueOfClassConstant` + - `Psalm\Type\Atomic\TVoid` + - `Psalm\Type\Union` +- While not a BC break per se, all classes / interfaces / traits / enums under + `Psalm\Internal` namespace are now marked `@internal`. +- [BC] Parameter 1 of `Psalm\Type\Atomic\TNamedObject::__construct()` changed name from `was_static` to `is_static` +- [BC] Parameter 1 of `Psalm\Type\Atomic\TAnonymousClassInstance::__construct()` changed name from `was_static` to `is_static` +- [BC] Parameter 5 of `Psalm\Type::getStringFromFQCLN()` changed name from `was_static` to `is_static` +- [BC] Property `Psalm\Type\Atomic\TNamedObject::$was_static` was renamed to `$is_static` +- [BC] Method `Psalm\Type\Union::isFormerStaticObject()` was renamed to `isStaticObject()` +- [BC] Method `Psalm\Type\Union::hasFormerStaticObject()` was renamed to `hasStaticObject()` +- [BC] Function assertions (from `@psalm-assert Foo $bar`) have been converted from strings to specific `Assertion` objects. +- [BC] Property `Psalm\Storage\ClassLikeStorage::$invalid_dependencies` changed from `array` to `array`. ## Removed - [BC] Property `Psalm\Codebase::$php_major_version` was removed, use diff --git a/docs/running_psalm/plugins/plugins_type_system.md b/docs/running_psalm/plugins/plugins_type_system.md index 031cb16ad09..c59e4c1a465 100644 --- a/docs/running_psalm/plugins/plugins_type_system.md +++ b/docs/running_psalm/plugins/plugins_type_system.md @@ -83,7 +83,7 @@ All scalar types have literal versions e.g. `int` vs `int(5)`. `TLiteralInt` - is used to represent an integer value where the exact numeric value is known. -`TPositiveInt` - denotes an int that is also positive (strictly > 0) +`TIntRange` - allows to describe an int with bounded values (ie. `int<1, 5>`). #### Floats diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 87b803b17ce..555cf65851b 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -126,12 +126,6 @@ - - new TPositiveInt() - - - Type::getPositiveInt(true) - $invalid_left_messages[0] $invalid_right_messages[0] @@ -164,13 +158,6 @@ $stmt->getArgs()[0] - - - new TPositiveInt - new TPositiveInt - new TPositiveInt - - $result->invalid_method_call_types[0] @@ -328,20 +315,7 @@ $cs[0] - - - TPositiveInt::class - - - - - TPositiveInt::class - - - - new TPositiveInt() - $combination->array_type_params[1] $combination->array_type_params[1] @@ -352,9 +326,6 @@ - - new TPositiveInt() - $intersection_types[0] $parse_tree->children[0] @@ -398,11 +369,6 @@ addFileExtension - - - new TPositiveInt() - - array_keys($template_type_map[$value])[0] diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php index af55952a1ea..0094be6183c 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php @@ -147,7 +147,7 @@ public static function analyze( $array_type = new TList($item_value_type ?? Type::getMixed()); } else { $array_type = new TNonEmptyList($item_value_type ?? Type::getMixed()); - /** @psalm-suppress PossiblyInvalidPropertyAssignmentValue */ + /** @psalm-suppress InvalidPropertyAssignmentValue */ $array_type->count = count($array_creation_info->property_types); } @@ -235,7 +235,7 @@ public static function analyze( $item_value_type ?? Type::getMixed(), ]); - /** @psalm-suppress PossiblyInvalidPropertyAssignmentValue */ + /** @psalm-suppress InvalidPropertyAssignmentValue */ $array_type->count = count($array_creation_info->property_types); $stmt_type = new Union([ diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php index 037f426ec20..091ed537c2e 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php @@ -40,7 +40,6 @@ use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TNumeric; use Psalm\Type\Atomic\TNumericString; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TString; use Psalm\Type\Atomic\TTemplateParam; use Psalm\Type\Union; @@ -728,11 +727,11 @@ private static function analyzeOperands( if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Div) { $result_type = new Union([new TInt(), new TFloat()]); } else { - $left_is_positive = $left_type_part instanceof TPositiveInt - || ($left_type_part instanceof TLiteralInt && $left_type_part->value > 0); + $left_is_positive = ($left_type_part instanceof TLiteralInt && $left_type_part->value > 0) + || ($left_type_part instanceof TIntRange && $left_type_part->isPositive()); - $right_is_positive = $right_type_part instanceof TPositiveInt - || ($right_type_part instanceof TLiteralInt && $right_type_part->value > 0); + $right_is_positive = ($right_type_part instanceof TLiteralInt && $right_type_part->value > 0) + || ($right_type_part instanceof TIntRange && $right_type_part->isPositive()); if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Minus) { $always_positive = false; @@ -772,17 +771,14 @@ private static function analyzeOperands( } } else { if ($always_positive) { - $result_type = new Union([ - new TPositiveInt(), - new TLiteralInt(0) - ]); + $result_type = new Union([new TIntRange(0, null)]); } else { $result_type = Type::getInt(); } } } else { $result_type = Type::combineUnionTypes( - $always_positive ? Type::getPositiveInt(true) : Type::getInt(true), + $always_positive ? new Union([new TIntRange(1, null)]) : Type::getInt(true), $result_type ); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php index c74c6ebac10..afe36e9b8e1 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php @@ -41,7 +41,6 @@ use Psalm\Type\Atomic\TNonEmptyArray; use Psalm\Type\Atomic\TNonEmptyList; use Psalm\Type\Atomic\TNull; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Union; use UnexpectedValueException; @@ -373,7 +372,7 @@ private static function getReturnTypeFromCallMapWithArgs( return new Union([ $atomic_types['array']->count !== null ? new TLiteralInt($atomic_types['array']->count) - : new TPositiveInt + : new TIntRange(1, null) ]); } @@ -381,7 +380,7 @@ private static function getReturnTypeFromCallMapWithArgs( return new Union([ $atomic_types['array']->count !== null ? new TLiteralInt($atomic_types['array']->count) - : new TPositiveInt + : new TIntRange(1, null) ]); } @@ -422,8 +421,7 @@ private static function getReturnTypeFromCallMapWithArgs( } return new Union([ - new TLiteralInt(0), - new TPositiveInt + new TIntRange(0, null) ]); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php index e4af074ccff..c76bcfd70b7 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php @@ -72,7 +72,6 @@ use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TObject; use Psalm\Type\Atomic\TObjectWithProperties; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TSingleLetter; use Psalm\Type\Atomic\TString; use Psalm\Type\Atomic\TTemplateIndexedAccess; @@ -891,11 +890,6 @@ private static function checkLiteralIntArrayOffset( $found_match = true; break; } - - if ($offset_type_part instanceof TPositiveInt) { - $found_match = true; - break; - } } if (!$found_match) { diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/UnaryPlusMinusAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/UnaryPlusMinusAnalyzer.php index 4bc7a4388d4..b46ac3df06c 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/UnaryPlusMinusAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/UnaryPlusMinusAnalyzer.php @@ -16,7 +16,6 @@ use Psalm\Type\Atomic\TIntRange; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TString; use Psalm\Type\Union; @@ -81,12 +80,6 @@ public static function analyze( } } - if ($type_part instanceof TPositiveInt - && $stmt instanceof PhpParser\Node\Expr\UnaryMinus - ) { - $type_part = new TIntRange(null, -1); - } - $acceptable_types[] = $type_part; } elseif ($type_part instanceof TString) { $acceptable_types[] = new TInt; diff --git a/src/Psalm/Internal/Diff/AstDiffer.php b/src/Psalm/Internal/Diff/AstDiffer.php index b0588459670..7ab61cee590 100644 --- a/src/Psalm/Internal/Diff/AstDiffer.php +++ b/src/Psalm/Internal/Diff/AstDiffer.php @@ -40,6 +40,7 @@ protected static function calculateTrace( $n = count($a); $m = count($b); $max = $n + $m; + /** @var array $v */ $v = [1 => 0]; $bc = []; $trace = []; diff --git a/src/Psalm/Internal/Diff/FileDiffer.php b/src/Psalm/Internal/Diff/FileDiffer.php index c50d44660a7..675ce5c2c08 100644 --- a/src/Psalm/Internal/Diff/FileDiffer.php +++ b/src/Psalm/Internal/Diff/FileDiffer.php @@ -40,6 +40,7 @@ private static function calculateTrace( $n = count($a); $m = count($b); $max = $n + $m; + /** @var array $v */ $v = [1 => 0]; $trace = []; for ($d = 0; $d <= $max; ++$d) { diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillReturnTypeProvider.php index 03dc378d46a..07dd6089498 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillReturnTypeProvider.php @@ -97,10 +97,6 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev private static function isPositiveNumericType(Union $arg): bool { - if ($arg->isSingle() && $arg->hasPositiveInt()) { - return true; - } - if ($arg->isSingle()) { foreach ($arg->getRangeInts() as $range_int) { if ($range_int->isPositive()) { diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/MinMaxReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/MinMaxReturnTypeProvider.php index d8eba498963..894c78ba786 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/MinMaxReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/MinMaxReturnTypeProvider.php @@ -11,7 +11,6 @@ use Psalm\Type\Atomic\TInt; use Psalm\Type\Atomic\TIntRange; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Union; use UnexpectedValueException; @@ -72,9 +71,6 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev } elseif ($atomic_type instanceof TIntRange) { $min_bounds[] = $atomic_type->min_bound; $max_bounds[] = $atomic_type->max_bound; - } elseif ($atomic_type instanceof TPositiveInt) { - $min_bounds[] = 1; - $max_bounds[] = null; } elseif (get_class($atomic_type) === TInt::class) { $min_bounds[] = null; $max_bounds[] = null; @@ -119,15 +115,6 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev $return_type = null; foreach ($call_args as $arg) { if ($array_arg_type = $nodeTypeProvider->getType($arg->value)) { - if ($array_arg_type->isSingle()) { - $atomic_type = $array_arg_type->getSingleAtomic(); - if ($atomic_type instanceof TPositiveInt) { - //we replace TPositiveInt with a range for better combination - $array_arg_type->removeType('int'); - $array_arg_type->addType(new TIntRange(1, null)); - } - } - $return_type = Type::combineUnionTypes( $return_type, $array_arg_type diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/RandReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/RandReturnTypeProvider.php index 7d72ceb941f..7ccfce13c35 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/RandReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/RandReturnTypeProvider.php @@ -9,7 +9,6 @@ use Psalm\Type; use Psalm\Type\Atomic\TIntRange; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Union; use function count; @@ -51,8 +50,6 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev $min_value = $first_atomic_type->value; } elseif ($first_atomic_type instanceof TIntRange) { $min_value = $first_atomic_type->min_bound; - } elseif ($first_atomic_type instanceof TPositiveInt) { - $min_value = 1; } } @@ -63,8 +60,6 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev $max_value = $second_atomic_type->value; } elseif ($second_atomic_type instanceof TIntRange) { $max_value = $second_atomic_type->max_bound; - } elseif ($second_atomic_type instanceof TPositiveInt) { - // no max value, we keep null } } diff --git a/src/Psalm/Internal/Type/AssertionReconciler.php b/src/Psalm/Internal/Type/AssertionReconciler.php index b2567500ee0..7c9c53adccd 100644 --- a/src/Psalm/Internal/Type/AssertionReconciler.php +++ b/src/Psalm/Internal/Type/AssertionReconciler.php @@ -50,7 +50,6 @@ use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TNumeric; use Psalm\Type\Atomic\TObject; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TScalar; use Psalm\Type\Atomic\TString; use Psalm\Type\Atomic\TTemplateParam; @@ -781,19 +780,7 @@ private static function filterAtomicWithAnother( //These partial match wouldn't have been handled by AtomicTypeComparator $new_range = null; - if ($type_2_atomic instanceof TIntRange && $type_1_atomic instanceof TPositiveInt) { - $new_range = TIntRange::intersectIntRanges( - TIntRange::convertToIntRange($type_1_atomic), - $type_2_atomic - ); - } elseif ($type_1_atomic instanceof TIntRange - && $type_2_atomic instanceof TPositiveInt - ) { - $new_range = TIntRange::intersectIntRanges( - $type_1_atomic, - TIntRange::convertToIntRange($type_2_atomic) - ); - } elseif ($type_2_atomic instanceof TIntRange + if ($type_2_atomic instanceof TIntRange && $type_1_atomic instanceof TIntRange ) { $new_range = TIntRange::intersectIntRanges( @@ -1012,10 +999,6 @@ private static function handleLiteralEqualityWithInt( } foreach ($existing_var_atomic_types as $existing_var_atomic_type) { - if ($existing_var_atomic_type instanceof TPositiveInt && $value > 0) { - return $literal_asserted_type; - } - if ($existing_var_atomic_type instanceof TIntRange && $existing_var_atomic_type->contains($value)) { return $literal_asserted_type; } diff --git a/src/Psalm/Internal/Type/Comparator/IntegerRangeComparator.php b/src/Psalm/Internal/Type/Comparator/IntegerRangeComparator.php index 486a4df8c71..6b98ebb6c4c 100644 --- a/src/Psalm/Internal/Type/Comparator/IntegerRangeComparator.php +++ b/src/Psalm/Internal/Type/Comparator/IntegerRangeComparator.php @@ -7,7 +7,6 @@ use Psalm\Type\Atomic\TIntRange; use Psalm\Type\Atomic\TLiteralInt; use Psalm\Type\Atomic\TNonspecificLiteralInt; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Union; use UnexpectedValueException; @@ -62,17 +61,7 @@ public static function isContainedByUnion( return true; } - if (get_class($container_atomic_types['int']) === TPositiveInt::class) { - if ($input_type_part->isPositive()) { - return true; - } - - //every positive integer is satisfied by the positive-int int container so we reduce the range - $reduced_range->max_bound = 0; - unset($container_atomic_types['int']); - } else { - throw new UnexpectedValueException('Should not happen: unknown int key'); - } + throw new UnexpectedValueException('Should not happen: unknown int key'); } $new_nb_atomics = count($container_atomic_types); diff --git a/src/Psalm/Internal/Type/Comparator/ScalarTypeComparator.php b/src/Psalm/Internal/Type/Comparator/ScalarTypeComparator.php index e4883793c8a..326b3310b1d 100644 --- a/src/Psalm/Internal/Type/Comparator/ScalarTypeComparator.php +++ b/src/Psalm/Internal/Type/Comparator/ScalarTypeComparator.php @@ -32,7 +32,6 @@ use Psalm\Type\Atomic\TNonspecificLiteralString; use Psalm\Type\Atomic\TNumeric; use Psalm\Type\Atomic\TNumericString; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TScalar; use Psalm\Type\Atomic\TSingleLetter; use Psalm\Type\Atomic\TString; @@ -307,8 +306,7 @@ public static function isContainedBy( } if (get_class($container_type_part) === TDependentListKey::class - && ($input_type_part instanceof TLiteralInt - || $input_type_part instanceof TPositiveInt) + && $input_type_part instanceof TLiteralInt ) { return true; } @@ -369,11 +367,7 @@ public static function isContainedBy( return true; } - if ((get_class($input_type_part) === TInt::class && $container_type_part instanceof TLiteralInt) - || (get_class($input_type_part) === TPositiveInt::class - && $container_type_part instanceof TLiteralInt - && $container_type_part->value > 0) - ) { + if (get_class($input_type_part) === TInt::class && $container_type_part instanceof TLiteralInt) { if ($atomic_comparison_result) { $atomic_comparison_result->type_coerced = true; $atomic_comparison_result->type_coerced_from_scalar = true; @@ -389,49 +383,7 @@ public static function isContainedBy( ); } - if ($input_type_part instanceof TInt && $container_type_part instanceof TPositiveInt) { - if ($input_type_part instanceof TPositiveInt) { - return true; - } - if ($input_type_part instanceof TLiteralInt) { - return $input_type_part->value > 0; - } - if ($input_type_part instanceof TIntRange) { - return $input_type_part->isPositive(); - } - - if ($atomic_comparison_result) { - $atomic_comparison_result->type_coerced = true; - $atomic_comparison_result->type_coerced_from_scalar = true; - } - - return false; - } - if ($input_type_part instanceof TInt && $container_type_part instanceof TIntRange) { - if ($input_type_part instanceof TPositiveInt) { - if ($container_type_part->min_bound > 1) { - //any positive int can't be pushed inside a range with a min > 1 - if ($atomic_comparison_result) { - $atomic_comparison_result->type_coerced = true; - $atomic_comparison_result->type_coerced_from_scalar = true; - } - - return false; - } - - if ($container_type_part->max_bound !== null) { - //any positive int can't be pushed inside a range where the max bound isn't max without coercion - if ($atomic_comparison_result) { - $atomic_comparison_result->type_coerced = true; - $atomic_comparison_result->type_coerced_from_scalar = true; - } - - return false; - } - - return true; - } if ($input_type_part instanceof TLiteralInt) { $min_bound = $container_type_part->min_bound; $max_bound = $container_type_part->max_bound; diff --git a/src/Psalm/Internal/Type/Comparator/UnionTypeComparator.php b/src/Psalm/Internal/Type/Comparator/UnionTypeComparator.php index 288f3e25845..2d0a6531d8b 100644 --- a/src/Psalm/Internal/Type/Comparator/UnionTypeComparator.php +++ b/src/Psalm/Internal/Type/Comparator/UnionTypeComparator.php @@ -12,7 +12,6 @@ use Psalm\Type\Atomic\TMixed; use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TNumeric; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TTemplateParam; use Psalm\Type\Atomic\TTypeAlias; use Psalm\Type\Union; @@ -413,24 +412,8 @@ public static function canExpressionTypesBeIdentical( foreach (self::getTypeParts($codebase, $type1) as $type1_part) { foreach (self::getTypeParts($codebase, $type2) as $type2_part) { - //special cases for TIntRange because it can contain a part of the other type. - //For exemple int<0,1> and positive-int can be identical but none contain the other - if (($type1_part instanceof TIntRange && $type2_part instanceof TPositiveInt)) { - $intersection_range = TIntRange::intersectIntRanges( - TIntRange::convertToIntRange($type2_part), - $type1_part - ); - return $intersection_range !== null; - } - - if ($type2_part instanceof TIntRange && $type1_part instanceof TPositiveInt) { - $intersection_range = TIntRange::intersectIntRanges( - TIntRange::convertToIntRange($type1_part), - $type2_part - ); - return $intersection_range !== null; - } - + //special case for TIntRange because it can contain a part of another TIntRange. + //For exemple int<0,10> and int<5, 15> can be identical but none contain the other if ($type1_part instanceof TIntRange && $type2_part instanceof TIntRange) { $intersection_range = TIntRange::intersectIntRanges( $type1_part, diff --git a/src/Psalm/Internal/Type/NegatedAssertionReconciler.php b/src/Psalm/Internal/Type/NegatedAssertionReconciler.php index 0f9b5de93a6..04bd0e1622e 100644 --- a/src/Psalm/Internal/Type/NegatedAssertionReconciler.php +++ b/src/Psalm/Internal/Type/NegatedAssertionReconciler.php @@ -320,9 +320,7 @@ private static function handleLiteralNegatedEquality( if ($assertion_type instanceof TLiteralInt) { if ($existing_var_type->hasInt()) { if ($existing_var_type->getLiteralInts()) { - if (!$existing_var_type->hasPositiveInt()) { - $did_match_literal_type = true; - } + $did_match_literal_type = true; if ($existing_var_type->removeType($assertion_type->getKey())) { $did_remove_type = true; diff --git a/src/Psalm/Internal/Type/SimpleAssertionReconciler.php b/src/Psalm/Internal/Type/SimpleAssertionReconciler.php index e39cfa81932..7d36198f4b5 100644 --- a/src/Psalm/Internal/Type/SimpleAssertionReconciler.php +++ b/src/Psalm/Internal/Type/SimpleAssertionReconciler.php @@ -65,7 +65,6 @@ use Psalm\Type\Atomic\TNumericString; use Psalm\Type\Atomic\TObject; use Psalm\Type\Atomic\TObjectWithProperties; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TResource; use Psalm\Type\Atomic\TScalar; use Psalm\Type\Atomic\TString; @@ -1669,12 +1668,6 @@ private static function reconcileSuperiorTo( $existing_var_type->addType(new TIntRange($assertion_value, $atomic_type->value)); } }*/ - } elseif ($atomic_type instanceof TPositiveInt) { - if ($assertion_value > 1) { - $did_remove_type = true; - $existing_var_type->removeType($atomic_type->getKey()); - $existing_var_type->addType(new TIntRange($assertion_value, null)); - } } elseif ($atomic_type instanceof TInt) { $did_remove_type = true; $existing_var_type->removeType($atomic_type->getKey()); @@ -1775,12 +1768,6 @@ private static function reconcileInferiorTo( $existing_var_type->addType(new TIntRange($assertion_value, $atomic_type->value)); } }*/ - } elseif ($atomic_type instanceof TPositiveInt) { - $did_remove_type = true; - $existing_var_type->removeType($atomic_type->getKey()); - if ($assertion_value >= 1) { - $existing_var_type->addType(new TIntRange(1, $assertion_value)); - } } elseif ($atomic_type instanceof TInt) { $did_remove_type = true; $existing_var_type->removeType($atomic_type->getKey()); diff --git a/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php b/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php index 37940d9dd20..548ec187b79 100644 --- a/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php +++ b/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php @@ -54,7 +54,6 @@ use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TNumeric; use Psalm\Type\Atomic\TObject; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TResource; use Psalm\Type\Atomic\TScalar; use Psalm\Type\Atomic\TString; @@ -1712,12 +1711,6 @@ private static function reconcileIsLessThanOrEqualTo( $existing_var_type->addType(new TIntRange($assertion_value, $atomic_type->value)); } }*/ - } elseif ($atomic_type instanceof TPositiveInt) { - $did_remove_type = true; - $existing_var_type->removeType($atomic_type->getKey()); - if ($assertion_value >= 1) { - $existing_var_type->addType(new TIntRange(1, $assertion_value)); - } } elseif ($atomic_type instanceof TInt) { $did_remove_type = true; $existing_var_type->removeType($atomic_type->getKey()); @@ -1818,12 +1811,6 @@ private static function reconcileIsGreaterThanOrEqualTo( $existing_var_type->addType(new TIntRange($assertion_value, $atomic_type->value)); } }*/ - } elseif ($atomic_type instanceof TPositiveInt) { - if ($assertion_value > 1) { - $did_remove_type = true; - $existing_var_type->removeType($atomic_type->getKey()); - $existing_var_type->addType(new TIntRange($assertion_value, null)); - } } elseif ($atomic_type instanceof TInt) { $did_remove_type = true; $existing_var_type->removeType($atomic_type->getKey()); diff --git a/src/Psalm/Internal/Type/TypeCombiner.php b/src/Psalm/Internal/Type/TypeCombiner.php index bc3d5a29f50..69ec72bfb5a 100644 --- a/src/Psalm/Internal/Type/TypeCombiner.php +++ b/src/Psalm/Internal/Type/TypeCombiner.php @@ -47,7 +47,6 @@ use Psalm\Type\Atomic\TNumericString; use Psalm\Type\Atomic\TObject; use Psalm\Type\Atomic\TObjectWithProperties; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TScalar; use Psalm\Type\Atomic\TString; use Psalm\Type\Atomic\TTemplateParam; @@ -1140,13 +1139,7 @@ private static function scrapeIntProperties( return; } - $had_zero = isset($combination->ints['int(0)']); - if ($type instanceof TLiteralInt) { - if ($type->value === 0) { - $had_zero = true; - } - if ($combination->ints !== null && count($combination->ints) < $literal_limit) { $combination->ints[$type_key] = $type; } else { @@ -1179,40 +1172,12 @@ private static function scrapeIntProperties( if (!isset($combination->value_types['int'])) { $combination->value_types['int'] = $all_nonnegative - ? new TPositiveInt() + ? new TIntRange(1, null) : new TNonspecificLiteralInt(); - } elseif ($combination->value_types['int'] instanceof TPositiveInt - && !$all_nonnegative - ) { - $combination->value_types['int'] = new TInt(); } } } else { - if ($type instanceof TPositiveInt) { - if ($combination->ints) { - $all_nonnegative = !array_filter( - $combination->ints, - fn($int): bool => $int->value < 0 - ); - - if ($all_nonnegative) { - $combination->value_types['int'] = $type; - } else { - $combination->value_types['int'] = new TInt(); - } - } elseif (!isset($combination->value_types['int'])) { - $combination->value_types['int'] = $type; - } elseif ($combination->value_types['int'] instanceof TIntRange) { - //if we already had a range, we ensure the min is no higher than 1 - $combination->value_types['int']->min_bound = TIntRange::getNewLowestBound( - $combination->value_types['int']->min_bound, - 1 - ); - $combination->value_types['int']->max_bound = null; - } elseif (get_class($combination->value_types['int']) !== get_class($type)) { - $combination->value_types['int'] = new TInt(); - } - } elseif ($type instanceof TNonspecificLiteralInt) { + if ($type instanceof TNonspecificLiteralInt) { if ($combination->ints || !isset($combination->value_types['int'])) { $combination->value_types['int'] = $type; } elseif (isset($combination->value_types['int']) @@ -1238,9 +1203,6 @@ private static function scrapeIntProperties( if ($old_type instanceof TIntRange) { $type->min_bound = TIntRange::getNewLowestBound($old_type->min_bound, $type->min_bound); $type->max_bound = TIntRange::getNewHighestBound($old_type->max_bound, $type->max_bound); - } elseif ($old_type instanceof TPositiveInt) { - $type->min_bound = TIntRange::getNewLowestBound($type->min_bound, 0); - $type->max_bound = null; } else { $type = new TInt(); } @@ -1252,18 +1214,6 @@ private static function scrapeIntProperties( $combination->ints = null; } - - if ($had_zero - && isset($combination->value_types['int']) - && $combination->value_types['int'] instanceof TPositiveInt - ) { - if ($combination->ints === null) { - $combination->ints = ['int(0)' => new TLiteralInt(0)]; - } elseif ($type instanceof TLiteralInt && $type->value < 0) { - $combination->ints = null; - $combination->value_types['int'] = new TInt(); - } - } } /** diff --git a/src/Psalm/Internal/Type/TypeParser.php b/src/Psalm/Internal/Type/TypeParser.php index bf10c2778eb..9e2fc4dba8b 100644 --- a/src/Psalm/Internal/Type/TypeParser.php +++ b/src/Psalm/Internal/Type/TypeParser.php @@ -55,7 +55,6 @@ use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TObject; use Psalm\Type\Atomic\TObjectWithProperties; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TTemplateIndexedAccess; use Psalm\Type\Atomic\TTemplateKeyOf; use Psalm\Type\Atomic\TTemplateParam; @@ -857,10 +856,6 @@ private static function getTypeFromGenericTree( return new TInt(); } - if ($min_bound === 1 && $max_bound === null) { - return new TPositiveInt(); - } - return new TIntRange($min_bound, $max_bound); } diff --git a/src/Psalm/Type.php b/src/Psalm/Type.php index 63d793b1f51..88c31bac377 100644 --- a/src/Psalm/Type.php +++ b/src/Psalm/Type.php @@ -37,7 +37,6 @@ use Psalm\Type\Atomic\TNumericString; use Psalm\Type\Atomic\TObject; use Psalm\Type\Atomic\TObjectWithProperties; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TResource; use Psalm\Type\Atomic\TScalar; use Psalm\Type\Atomic\TSingleLetter; @@ -194,15 +193,6 @@ public static function getLowercaseString(): Union return new Union([$type]); } - /** @deprecated will be removed in Psalm 5 */ - public static function getPositiveInt(bool $from_calculation = false): Union - { - $union = new Union([new TPositiveInt()]); - $union->from_calculation = $from_calculation; - - return $union; - } - public static function getNonEmptyLowercaseString(): Union { $type = new TNonEmptyLowercaseString(); diff --git a/src/Psalm/Type/Atomic.php b/src/Psalm/Type/Atomic.php index 9932e9b0571..382a893fdfb 100644 --- a/src/Psalm/Type/Atomic.php +++ b/src/Psalm/Type/Atomic.php @@ -58,7 +58,6 @@ use Psalm\Type\Atomic\TNumericString; use Psalm\Type\Atomic\TObject; use Psalm\Type\Atomic\TObjectWithProperties; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TResource; use Psalm\Type\Atomic\TScalar; use Psalm\Type\Atomic\TString; @@ -701,10 +700,6 @@ public function isTruthy(): bool return true; } - if ($this instanceof TPositiveInt) { - return true; - } - if ($this instanceof TLiteralClassString) { return true; } diff --git a/src/Psalm/Type/Atomic/TIntRange.php b/src/Psalm/Type/Atomic/TIntRange.php index ffb6926c3e6..32254ae11fd 100644 --- a/src/Psalm/Type/Atomic/TIntRange.php +++ b/src/Psalm/Type/Atomic/TIntRange.php @@ -122,10 +122,6 @@ public static function convertToIntRange(TInt $int_atomic): TIntRange return $int_atomic; } - if ($int_atomic instanceof TPositiveInt) { - return new TIntRange(1, null); - } - if ($int_atomic instanceof TLiteralInt) { return new TIntRange($int_atomic->value, $int_atomic->value); } diff --git a/src/Psalm/Type/Atomic/TPositiveInt.php b/src/Psalm/Type/Atomic/TPositiveInt.php deleted file mode 100644 index dd8fd0f6ce8..00000000000 --- a/src/Psalm/Type/Atomic/TPositiveInt.php +++ /dev/null @@ -1,36 +0,0 @@ - 0) - * @deprecated will be removed in Psalm 5 - */ -class TPositiveInt extends TInt -{ - public function getId(bool $exact = true, bool $nested = false): string - { - return 'positive-int'; - } - - /** - * @return false - */ - public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool - { - return false; - } - - /** - * @param array $aliased_classes - * - */ - public function toNamespacedString( - ?string $namespace, - array $aliased_classes, - ?string $this_class, - bool $use_phpdoc_format - ): string { - return $use_phpdoc_format ? 'int' : 'positive-int'; - } -} diff --git a/src/Psalm/Type/Union.php b/src/Psalm/Type/Union.php index 84e8cdb0c2b..dd949d61f8c 100644 --- a/src/Psalm/Type/Union.php +++ b/src/Psalm/Type/Union.php @@ -38,7 +38,6 @@ use Psalm\Type\Atomic\TNonEmptyLowercaseString; use Psalm\Type\Atomic\TNonspecificLiteralInt; use Psalm\Type\Atomic\TNonspecificLiteralString; -use Psalm\Type\Atomic\TPositiveInt; use Psalm\Type\Atomic\TString; use Psalm\Type\Atomic\TTemplateParam; use Psalm\Type\Atomic\TTemplateParamClass; @@ -856,11 +855,6 @@ public function hasInt(): bool || array_filter($this->types, fn(Atomic $type) => $type instanceof TIntRange); } - public function hasPositiveInt(): bool - { - return isset($this->types['int']) && $this->types['int'] instanceof TPositiveInt; - } - public function hasArrayKey(): bool { return isset($this->types['array-key']); diff --git a/tests/ArrayAccessTest.php b/tests/ArrayAccessTest.php index d368979b190..c8f9b171776 100644 --- a/tests/ArrayAccessTest.php +++ b/tests/ArrayAccessTest.php @@ -1018,7 +1018,7 @@ function bar(int $i) { if ($foo !== null) {}' ], - 'accessKnownArrayWithPositiveInt' => [ + 'SKIPPED-accessKnownArrayWithPositiveInt' => [ 'code' => ' $arr */ function foo(array $arr) : void { diff --git a/tests/Loop/ForTest.php b/tests/Loop/ForTest.php index b8781a116e3..dfc9b605a83 100644 --- a/tests/Loop/ForTest.php +++ b/tests/Loop/ForTest.php @@ -64,6 +64,7 @@ function test(): int { 'preventNegativeZeroScrewingThingsUp' => [ 'code' => ' $v */ $v = [1 => 0]; for ($d = 0; $d <= 10; $d++) { for ($k = -$d; $k <= $d; $k += 2) {