-
Notifications
You must be signed in to change notification settings - Fork 369
Description
This is best explained by the demo, but if you have an array for which phan can not determine the types (e.g. decoded from a JSON string), the first operation that returns a type (e.g. where phan knows a certain array key at that point is a certain type), it sets the type to an ArrayShapeType with that type only. This then means that operations on different keys can fail due to a type mismatch.
Potentially related, is that if the loop is removed, after the first operation on the array, phan then believes that key is the only key that exists. With this, provides information on the structure of the array resolves the feedback that the second array key is not defined, but the strlen seems to override the type information provided in the comment.
Test code 1:
<?php
class Foo{
public function __construct(string $bar){
$barArr = json_decode($bar, true);
//'@phan-var list<array{x:string,y:string}> $barArr'; // If this is uncommented, phan provides no output
foreach($barArr as $barRow){
$barRow["x"] = \strlen($barRow["x"]);
$barRow["y"] = \strlen($barRow["y"]);
}
}
}
Expected output: None
Actual output:
test2.php:7 PhanTypeMismatchArgumentInternal Argument 1 ($string) is $barRow['y'] of type int but \strlen() takes string
Test code 2:
<?php
class Foo{
public function __construct(string $bar){
$barArr = json_decode($bar, true);
if(count($barArr) > 0){ // Needed so phan knows that $barArr[0] is set
$barArr[0]["x"] = \strlen($barArr[0]["x"]); // Changing this to echo $barArr[0]["x"]; causes no output as expected
$barArr[0]["y"] = \strlen($barArr[0]["y"]);
}
}
}
Expected output: None
Actual output:
test2.php:7 PhanTypeInvalidDimOffset Invalid offset "y" of $barArr[0] of array type array{x:int}
test2.php:7 PhanTypeMismatchArgumentInternal Argument 1 ($string) is $barArr[0]['y'] of type null but \strlen() takes string
Test code 3:
<?php
class Foo{
public function __construct(string $bar){
$barArr = json_decode($bar, true);
'@phan-var list<array{x:string,y:string}> $barArr';
if(count($barArr) > 0){ // Needed so phan knows that $barArr[0] is set
$barArr[0]["x"] = \strlen($barArr[0]["x"]); // Changing this to echo $barArr[0]["x"]; causes no output as expected
$barArr[0]["y"] = \strlen($barArr[0]["y"]);
}
}
}
Expected output: None
Actual output:
test2.php:8 PhanTypeMismatchArgumentInternal Argument 1 ($string) is $barRow['y'] of type int but \strlen() takes string