I found these snippets:
https://psalm.dev/r/d46df351b7
<?php
/**
* @template T
*/
interface I
{
/**
* @param T $argument
*/
public function i($argument): void;
}
/**
* @implements I<int>
*/
class X implements I
{
public function i($argument): void
{
echo sprintf('%d', $argument);
}
}
/**
* @implements I<int>
*/
class XWithChangedArgumentName implements I
{
public function i($changedArgumentName): void
{
echo sprintf('%d', $changedArgumentName);
}
}
Psalm output (using commit 8f95c56):
INFO: MixedArgumentTypeCoercion - 32:24 - Argument 2 of sprintf expects float|int|string, parent type T:I as mixed provided
I don't _think_ this is a bug. The implicit inherited documentation refers only to a param named $argument – it says nothing about $changedArgument.
well, PHP itself inherits the signature regardless of the argument name
PHP itself inherits the signature regardless of the argument name
It doesn't though – this is perfectly valid:
class A {
public function takesInput(array $array) : void {}
}
class AChild extends A {
public function takesInput($mixed) : void {}
}
(new AChild())->takesInput("hello");
And by that logic I'd argue that PHPStan's behaviour here (newly-added) is incorrect: https://phpstan.org/r/552e0cc2-66dd-48bd-a6d4-cfbe9bdbf8f6
@muglug , basing on your logic, Psalm then should be enable to infer types for X (first implementation) either, because $argument has no type hint/declaration at all.
@muglug , a counter-argument to my issue could be the following: in pure PHP when you change the argument name, but leave the type the same, code breaks. But that's wrong.
@muglug guys are right here, parameter names have always been local to the function in PHP. It's the order that matters.
parameter names have always been local to the function in PHP. It's the order that matters.
Yes, but I'm asking about the intent of documenting those parent type parameters – is it to apply to all arguments in that position, or just to apply to things with that name in that position?
@muglug , to all arguments in that position, unless overridden by position in subclasses. Same as in PHP.
Yes, but I'm asking about the intent of documenting those parent type parameters – is it to apply to all arguments in that position, or just to apply to things with that name in that position?
To put it another way - if I'm free to choose the parameter names for my implementation when extending/implementing non-generic class/interface, extending generic one should behave the same.
And while we're all here, could you please have a look at my report https://github.com/vimeo/psalm/issues/2721 which was shaded by this one :-D
Fixed after I spent 20 minutes debugging an issue caused by this
Most helpful comment
Fixed after I spent 20 minutes debugging an issue caused by this