-
-
Notifications
You must be signed in to change notification settings - Fork 946
Closed
Description
Bug report
It looks like previous generics have some kind of state corruption bug that affects the resolution of generic classes analysed later on.
This bug requires that reportMaybesInMethodSignatures is set to true, so it can't be reproduced on the playground.
Version is 0.12.9.
Code snippet that reproduces the problem
<?php
declare(strict_types=1);
namespace pocketmine\entity2;
use function array_filter;
class BlockFactory{
/** @var \SplFixedArray<int> */
private static $fullList = null;
public static function isRegistered(int $id) : bool{
$b = self::$fullList[$id << 4]; //removing this line makes problem go away
return $b !== null;
}
}
class Attribute{
public function getId() : int{ return 0; }
public function isSyncable() : bool{ return false; }
public function isDesynchronized() : bool{ return false; }
public function getValue() : float{ return 0.0; }
public function setValue(float $f) : self{ return $this; }
}
/**
* @phpstan-implements \ArrayAccess<int, float>
*/
class AttributeMap implements \ArrayAccess{
/** @var Attribute[] */
private $attributes = [];
public function addAttribute(Attribute $attribute) : void{
$this->attributes[$attribute->getId()] = $attribute;
}
public function getAttribute(int $id) : ?Attribute{
return $this->attributes[$id] ?? null;
}
/**
* @return Attribute[]
*/
public function getAll() : array{
return $this->attributes;
}
/**
* @return Attribute[]
*/
public function needSend() : array{
return array_filter($this->attributes, function(Attribute $attribute){
return $attribute->isSyncable() and $attribute->isDesynchronized();
});
}
/**
* @param int $offset
*/
public function offsetExists($offset) : bool{
return isset($this->attributes[$offset]);
}
/**
* @param int $offset
*/
public function offsetGet($offset) : float{
return $this->attributes[$offset]->getValue();
}
/**
* @param int $offset
* @param float $value
*/
public function offsetSet($offset, $value) : void{
$this->attributes[$offset]->setValue($value);
}
/**
* @param int $offset
*/
public function offsetUnset($offset) : void{
throw new \RuntimeException("Could not unset an attribute from an attribute map");
}
}Playground doesn't reproduce, but it'll stop the bot complaining: https://phpstan.org/r/c280a23a-c4b2-46b7-a54f-476ca5dd27df
Analysis on level 8 with reportMaybesInMethodSignatures as true.
Expected output
No errors.
Actual output
------ ----------------------------------------------------------------------
Line test2.php
------ ----------------------------------------------------------------------
74 Parameter #1 $offset (int) of method
pocketmine\entity2\AttributeMap::offsetGet() should be contravariant
with parameter $offset (mixed) of method
ArrayAccess<int,float>::offsetGet()
82 Parameter #1 $offset (int) of method
pocketmine\entity2\AttributeMap::offsetSet() should be contravariant
with parameter $offset (mixed) of method
ArrayAccess<int,float>::offsetSet()
82 Parameter #2 $value (float) of method
pocketmine\entity2\AttributeMap::offsetSet() should be contravariant
with parameter $value (mixed) of method
ArrayAccess<int,float>::offsetSet()
------ ----------------------------------------------------------------------
[ERROR] Found 3 errors
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels