diff --git a/src/Psalm/Internal/Type/TypeParser.php b/src/Psalm/Internal/Type/TypeParser.php index dc25c783d0f..9f197d39370 100644 --- a/src/Psalm/Internal/Type/TypeParser.php +++ b/src/Psalm/Internal/Type/TypeParser.php @@ -442,6 +442,7 @@ public static function getComputedIntsFromMask(array $potential_ints) : array $potential_values = array_merge($new_values, $potential_values); } + array_unshift($potential_values, 0); $potential_values = array_unique($potential_values); return array_map( diff --git a/src/Psalm/Type/Atomic/TIntMask.php b/src/Psalm/Type/Atomic/TIntMask.php index f320d03f841..c7db8aa42dd 100644 --- a/src/Psalm/Type/Atomic/TIntMask.php +++ b/src/Psalm/Type/Atomic/TIntMask.php @@ -5,7 +5,7 @@ /** * Represents the type that is the result of a bitmask combination of its parameters. - * `int-mask<1, 2, 4>` corresponds to `1|2|3|4|5|6|7` + * `int-mask<1, 2, 4>` corresponds to `0|1|2|3|4|5|6|7` */ class TIntMask extends TInt { diff --git a/src/Psalm/Type/Atomic/TIntMaskOf.php b/src/Psalm/Type/Atomic/TIntMaskOf.php index fdd5cf4573b..27e3f80a545 100644 --- a/src/Psalm/Type/Atomic/TIntMaskOf.php +++ b/src/Psalm/Type/Atomic/TIntMaskOf.php @@ -4,7 +4,7 @@ /** * Represents the type that is the result of a bitmask combination of its parameters. * This is the same concept as TIntMask but TIntMaskOf is used with with a reference to constants in code - * `int-mask` will corresponds to `1|2|3|4|5|6|7` if there are three constant 1, 2 and 4 + * `int-mask` will corresponds to `0|1|2|3|4|5|6|7` if there are three constant 1, 2 and 4 */ class TIntMaskOf extends TInt { diff --git a/tests/AnnotationTest.php b/tests/AnnotationTest.php index 704aca08a89..f39d156bd30 100644 --- a/tests/AnnotationTest.php +++ b/tests/AnnotationTest.php @@ -1185,6 +1185,14 @@ function takesFlags(int $flags) : void { takesFlags(FileFlag::MODIFIED | FileFlag::NEW);' ], + 'intMaskWithZero' => [ + ' $_flags */ + function takesFlags(int $_flags): void {} + + takesFlags(0); + ' + ], 'intMaskOfWithClassWildcard' => [ ' [ + ' $_flags */ + function takesFlags(int $_flags): void {} + + takesFlags(0); + ' + ], 'emptyStringFirst' => [ ''); - $this->assertSame('1|2|3|4|5|6|7', $docblock_type->getId()); + $this->assertSame('0|1|2|3|4|5|6|7', $docblock_type->getId()); $docblock_type = Type::parseString('int-mask<1, 4>'); - $this->assertSame('1|4|5', $docblock_type->getId()); + $this->assertSame('0|1|4|5', $docblock_type->getId()); $docblock_type = Type::parseString('int-mask'); - $this->assertSame('1|256|257|512|513|768|769', $docblock_type->getId()); + $this->assertSame('0|1|256|257|512|513|768|769', $docblock_type->getId()); } public function testIntMaskWithClassConstant(): void