Psalm: MixedArgumentTypeCoercion if argument name is different

Created on 31 Jan 2020  Â·  13Comments  Â·  Source: vimeo/psalm

Most helpful comment

Fixed after I spent 20 minutes debugging an issue caused by this

All 13 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

roukmoute picture roukmoute  Â·  3Comments

vudaltsov picture vudaltsov  Â·  3Comments

zerkms picture zerkms  Â·  3Comments

Pierstoval picture Pierstoval  Â·  3Comments

tux-rampage picture tux-rampage  Â·  3Comments