psalm
psalm copied to clipboard
Creating variables in `match` (`PHP 8`) can lead to `PossiblyUndefinedVariable` and `MixedArgument` false-positive warnings
If you will try to create a variable in a new match
expression you can get PossiblyUndefinedVariable
and MixedArgument
false-positive warnings.
I did some examples: https://psalm.dev/r/3fcba079df
With the switch
statement it works fine and non-false-positive warnings are not appearing.
I found these snippets:
https://psalm.dev/r/3fcba079df
<?php
class A
{
public function some(): void
{
}
};
class B extends A {};
function fooMatch(string $case): void
{
match($case) {
'a' => $object = new A(),
'b' => $object = new B(),
default => throw new RuntimeException("Undefined case: $case")
};
bar($object);
bar(new A());
bar(new B());
}
function fooMatch2(string $case): void
{
match($case) {
'a' => $object = new A(),
'b' => $object = new B(),
default => $object = new B()
};
bar($object);
bar(new A());
bar(new B());
}
function fooSwitch(string $case): void
{
switch($case) {
case 'a':
$object = new A();
break;
case 'b':
$object = new B();
break;
default:
throw new RuntimeException("Undefined case: $case");
}
bar($object);
bar(new A());
bar(new B());
}
function fooSwitch2(string $case): void
{
switch($case) {
case 'a':
$object = new A();
break;
case 'b':
$object = new B();
break;
default:
$object = new A();
}
bar($object);
bar(new A());
bar(new B());
}
function bar(A $object): void
{
$object->some();
}
Psalm output (using commit 4b2935f):
INFO: PossiblyUndefinedVariable - 19:9 - Possibly undefined variable $object, first seen on line 14
INFO: MixedArgument - 19:9 - Argument 1 of bar cannot be mixed, expecting A
INFO: PossiblyUndefinedVariable - 33:9 - Possibly undefined variable $object, first seen on line 28
INFO: MixedArgument - 33:9 - Argument 1 of bar cannot be mixed, expecting A
In Rust and Scala (where match
is taken from), assigning the value of the match expression itself is more idiomatic anyway:
$object = match($case) {
'a' => new A(),
'b' => new B(),
default => throw new RuntimeException("Undefined case: $case")
};
https://psalm.dev/r/e01ceb02bf
I found these snippets:
https://psalm.dev/r/e01ceb02bf
<?php
class A
{
public function some(): void
{
}
};
class B extends A {};
function fooMatch(string $case): void
{
$object = match($case) {
'a' => new A(),
'b' => new B(),
default => throw new RuntimeException("Undefined case: $case")
};
bar($object);
bar(new A());
bar(new B());
}
function fooMatch2(string $case): void
{
$object = match($case) {
'a' => new A(),
'b' => new B(),
default => $object = new B()
};
bar($object);
bar(new A());
bar(new B());
}
function fooSwitch(string $case): void
{
switch($case) {
case 'a':
$object = new A();
break;
case 'b':
$object = new B();
break;
default:
throw new RuntimeException("Undefined case: $case");
}
bar($object);
bar(new A());
bar(new B());
}
function fooSwitch2(string $case): void
{
switch($case) {
case 'a':
$object = new A();
break;
case 'b':
$object = new B();
break;
default:
$object = new A();
}
bar($object);
bar(new A());
bar(new B());
}
function bar(A $object): void
{
$object->some();
}
Psalm output (using commit 4b2935f):
No issues!