When running Psalter on a method with a parameter type which is missing it appears tries to infer the type from usage, taking a union of the types that have been used to call the function.
But when one of these types is mixed the union of int and mixed is being converted to int not mixed (nor mixed | int).
This caused a bug in our production code. I've made a greatly simplified example in https://psalm.dev/r/d81512ff7e which exposes the bug (and also has a lot more types added than our real code did).
The type of $value is incorrectly being inferred as int|null not mixed or similar. This causes the code to break at runtime.
It is the case that by Psalter changing the type of $value in the function setInternal to be int|null I do get an error Argument 2 of ConfigContainer::setInternal expects int|null, but list{1, 2, 3, 4}|null provided but in a huge codebase that I'm trying to introduce Psalm to I already have a large number of similar errors and so sadly this gets lost in the noise.
As a new user of Psalm, I'm unsure if this is expected behaviour or not. I have a fairly large PHP codebase with very little type information and I'm hoping to have Psalm infer as many types as possible, either inline as PHP types like Psalm is doing here, or potentially preferably entirely as doc-blocks so that incorrect types don't break things (which might be safer on large legacy codebases with poor typing to avoid breaking code like this).
https://psalm.dev/r/d81512ff7e
```php
setInternal($name, $value);
}
public function setFoo(int $value): void
{
$this->setInternal('foo', $value);
}
private function setInternal(string $name, $value = null)
{
$this->values[$name] = $value;
}
public function getValues(): array
{
return $this->values;
}
}
$config = new ConfigContainer();
$config->setValue('userIds', [1,2,3,4]);
$config->setFoo(5);
print_r($config->getValues());
```
```
Psalm output (using commit 08f5b35):
INFO: MixedArrayAssignment - 19:9 - Cannot access array value on mixed variable $this->values[$name]
INFO: MissingParamType - 17:48 - Parameter $value has no provided type
INFO: MissingReturnType - 17:22 - Method ConfigContainer::setInternal does not have a return type, expecting void
INFO: MixedReturnStatement - 24:16 - Could not infer a return type
INFO: MixedInferredReturnType - 22:34 - Could not verify return type 'array' for ConfigContainer::getValues
INFO: MissingPropertyType - 5:13 - Property ConfigContainer::$values does not have a declared type - consider array|mixed
```
When running Psalter on a method with a parameter type which is missing it appears tries to infer the type from usage, taking a union of the types that have been used to call the function.
But when one of these types is
mixed
the union ofint
andmixed
is being converted toint
notmixed
(normixed | int
).This caused a bug in our production code. I've made a greatly simplified example in https://psalm.dev/r/d81512ff7e which exposes the bug (and also has a lot more types added than our real code did).
The type of
$value
is incorrectly being inferred asint|null
notmixed
or similar. This causes the code to break at runtime.It is the case that by Psalter changing the type of
$value
in the functionsetInternal
to beint|null
I do get an errorArgument 2 of ConfigContainer::setInternal expects int|null, but list{1, 2, 3, 4}|null provided
but in a huge codebase that I'm trying to introduce Psalm to I already have a large number of similar errors and so sadly this gets lost in the noise.As a new user of Psalm, I'm unsure if this is expected behaviour or not. I have a fairly large PHP codebase with very little type information and I'm hoping to have Psalm infer as many types as possible, either inline as PHP types like Psalm is doing here, or potentially preferably entirely as doc-blocks so that incorrect types don't break things (which might be safer on large legacy codebases with poor typing to avoid breaking code like this).