ArgumentTypeCoercion
Emitted when calling a function with an argument which has a less specific type than the function expects
<?php
class A {}
class B extends A {}
function takesA(A $a) : void {
takesB($a);
}
function takesB(B $b) : void {}
How to fix
You could add a typecheck before the call to takesB:
<?php
function takesA(A $a) : void {
if ($a instanceof B) {
takesB($a);
}
}
Or, if you have control over the function signature of takesA you can change it to expect B:
<?php
function takesA(B $a) : void {
takesB($a);
}
Built-in functions
Some built-in functions accept a narrower type than their native signature says, e.g. random_bytes() only accepts a positive-int:
<?php
function bad(int $length): string {
return random_bytes($length); // ArgumentTypeCoercion
}
Declare the narrower type of the parameter with @psalm-param:
<?php
/** @psalm-param positive-int $length */
function good(int $length): string {
return random_bytes($length); // no issue
}
Or check the value before the call, or assert its type with @psalm-var:
<?php
function checked(int $length): string {
if ($length < 1) {
throw new InvalidArgumentException('The length must be positive');
}
return random_bytes($length); // no issue
}
function asserted(int $length): string {
/** @psalm-var positive-int $length */
return random_bytes($length); // no issue
}