1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Narrow inference of $a <=> $b from "int" to "-1|0|1" (#4680)

* A <=> operator has a literal type of -1|0|1 and not simply int

* Test to verify inferred type of $a <=> $b is -1|0|1
This commit is contained in:
erikjwaxx 2020-11-23 13:10:51 -05:00 committed by GitHub
parent d151f1c36e
commit 25d8c6d21e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 2 deletions

View File

@ -161,7 +161,16 @@ class BinaryOpAnalyzer
}
if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Spaceship) {
$statements_analyzer->node_data->setType($stmt, Type::getInt());
$statements_analyzer->node_data->setType(
$stmt,
new Type\Union(
[
new Type\Atomic\TLiteralInt(-1),
new Type\Atomic\TLiteralInt(0),
new Type\Atomic\TLiteralInt(1)
]
)
);
self::addDataFlow(
$statements_analyzer,

View File

@ -100,7 +100,13 @@ class SimpleTypeInferer
}
if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Spaceship) {
return Type::getInt();
return new Type\Union(
[
new Type\Atomic\TLiteralInt(-1),
new Type\Atomic\TLiteralInt(0),
new Type\Atomic\TLiteralInt(1)
]
);
}
$stmt_left_type = self::infer(

View File

@ -318,6 +318,23 @@ class BinaryOperationTest extends TestCase
func("asdasdasd $a");
}'
],
'spaceshipOpIsLiteralUnionType' => [
'<?php
/**
* @psalm-param -1|0|1 $i
*/
function onlyZeroOrPlusMinusOne(int $i): int {
return $i;
}
/**
* @psalm-param mixed $a
* @psalm-param mixed $b
*/
function foo($a, $b): void {
onlyZeroOrPlusMinusOne($a <=> $b);
}'
]
];
}