psalm
psalm copied to clipboard
False positive InvalidCast when using `never` as template for class-string with template
https://psalm.dev/r/9a66468115
Probably somewhat related to #7913.
I found these snippets:
https://psalm.dev/r/9a66468115
<?php
/**
* @template T
* @psalm-consistent-constructor
*/
class Foo
{
/** @return ?T */
public function bar()
{
}
}
/** @extends Foo<string> */
class Foo1 extends Foo {}
/** @extends Foo<never> */
class Foo2 extends Foo {}
/**
* @template T
* @template TFoo of Foo<T>
*
* @param class-string<TFoo> $fooClass
* @return T
*/
function bar(string $fooClass)
{
return (new $fooClass)->bar();
}
/** @psalm-trace $baz */
$baz = bar(Foo1::class);
/** @psalm-trace $baz */
$baz = bar(Foo2::class);
Psalm output (using commit 85fe7e8):
INFO: Trace - 34:1 - $baz: string
ERROR: InvalidCast - 36:12 - Foo2 cannot be cast to string
ERROR: NoValue - 36:1 - This function or method call never returns output
I have the same error
https://psalm.dev/r/1cf2cacfc8
I found these snippets:
https://psalm.dev/r/1cf2cacfc8
<?php
/**
* @template TClass of object
*/
interface InjectorInterface {}
interface Binder {
/**
* @template TClass of object
*
* @param class-string<TClass> $class
* @param class-string<InjectorInterface<TClass>> $injector
*/
public function bindInjector(string $class, string $injector): void;
}
class Bar implements Binder {
public function __construct(
private Binder $binder,
){}
public function bindInjector(string $class, string $injector): void
{
$this->binder->bindInjector($class, $injector);
}
}
Psalm output (using commit e784128):
ERROR: InvalidCast - 23:45 - InjectorInterface<TClass:fn-binder::bindinjector as object> cannot be cast to string
fixed in https://github.com/vimeo/psalm/pull/9738 !