New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integer ranges not checked correctly #8838
Comments
I found these snippets: https://psalm.dev/r/75a668a862<?php declare(strict_types=1);
abstract class Piece
{
private readonly Position $position;
private function __construct(Position $position)
{
$this->position = $position;
}
/**
* @psalm-mutation-free
*/
public function position(): Position
{
return $this->position;
}
/**
* @psalm-param list<array{file: int, rank: int}> $offsets
*/
protected function offsetsToTargetPositionCandidates(array $offsets): void
{
$positions = [];
foreach ($offsets as $offset) {
$file = $this->position()->file() + $offset['file'];
$rank = $this->position()->rank() + $offset['rank'];
if ($file >= 1 && $file <= 8 && $rank >= 1 && $rank <= 8) {
$positions[] = Position::fromFileAndRank($file, $rank);
}
}
}
}
/**
* @psalm-immutable
*/
final class Position
{
/**
* @psalm-var int<1,8>
*/
private readonly int $file;
/**
* @psalm-var int<1,8>
*/
private readonly int $rank;
/**
* @psalm-param int<1,8> $file
* @psalm-param int<1,8> $rank
*/
public static function fromFileAndRank(int $file, int $rank): self
{
return new self($file, $rank);
}
/**
* @psalm-param int<1,8> $file
* @psalm-param int<1,8> $rank
*/
private function __construct(int $file, int $rank)
{
$this->file = $file;
$this->rank = $rank;
}
/**
* @psalm-return int<1,8>
*/
public function file(): int
{
return $this->file;
}
/**
* @psalm-return int<1,8>
*/
public function rank(): int
{
return $this->rank;
}
}
|
Interestingly, this workaround avoids the issue somehow. Psalm is apparently able to infer the correct types of the ints after comparisons in this case: https://psalm.dev/r/9251fdd044 |
I found these snippets: https://psalm.dev/r/9251fdd044<?php declare(strict_types=1);
abstract class Piece
{
private readonly Position $position;
private function __construct(Position $position)
{
$this->position = $position;
}
/**
* @psalm-mutation-free
*/
public function position(): Position
{
return $this->position;
}
/**
* @psalm-param list<array{file: int, rank: int}> $offsets
*/
protected function offsetsToTargetPositionCandidates(array $offsets): void
{
$positions = [];
foreach ($offsets as $offset) {
$file = $this->position()->file() + $offset['file'];
$rank = $this->position()->rank() + $offset['rank'];
$position = Position::fromFileAndRankIfWithinRange($file, $rank);
if ($position !== null) {
$positions[] = $position;
}
}
}
}
/**
* @psalm-immutable
*/
final class Position
{
/**
* @psalm-var int<1,8>
*/
private readonly int $file;
/**
* @psalm-var int<1,8>
*/
private readonly int $rank;
/**
* @psalm-param int<1,8> $file
* @psalm-param int<1,8> $rank
*/
public static function fromFileAndRank(int $file, int $rank): self
{
return new self($file, $rank);
}
/**
* @psalm-param int $file
* @psalm-param int $rank
*/
public static function fromFileAndRankIfWithinRange(int $file, int $rank): ?self
{
if ($file >= 1 && $file <= 8 && $rank >= 1 && $rank <= 8) {
return self::fromFileAndRank($file, $rank);
}
return null;
}
/**
* @psalm-param int<1,8> $file
* @psalm-param int<1,8> $rank
*/
private function __construct(int $file, int $rank)
{
$this->file = $file;
$this->rank = $rank;
}
/**
* @psalm-return int<1,8>
*/
public function file(): int
{
return $this->file;
}
/**
* @psalm-return int<1,8>
*/
public function rank(): int
{
return $this->rank;
}
}
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have a method
Position::fromFileAndRank()
that uses@psalm-param int<1,8>
annotations to limit the range of integer parameters to values >= 1 && <= 8:I have code that calls the method shown above after ensuring that the arguments to be passed are within the range the parameters expect:
But Psalm claims that the arguments are not within the range the parameters expect:
Reproducing example: https://psalm.dev/r/75a668a862
From the documentation of integer ranges it is not clear to me whether Psalm only allows literal integers or whether it should be able to infer that a variable is within range.
The text was updated successfully, but these errors were encountered: