Skip to content

Unioned classes' method signatures are too wide #9664

@zacharylund

Description

@zacharylund

Bug report

I would expect the call to setFoo() on Entity1|Entity2 to use the intersection of string and string|null (string) instead of the union (string|null).

Additional testing showed that Entity1::setFoo(int) and Entity2::setFoo(string) produces a method signature of Entity1|Entity2::setFoo(int|string).

<?php declare(strict_types = 1);

class Entity1
{
	public function setFoo(string $foo): void {}
}

class Entity2
{
	public function setFoo(?string $foo): void {}
}

function foo(Entity1|Entity2 $entity): void
{
	$entity->setFoo(null); // This should cause an error.
}

function foo1(Entity1 $entity): void
{
	$entity->setFoo(null); // This does produce an error.
}

function foo2(Entity2 $entity): void
{
	$entity->setFoo(null);
}

Code snippet that reproduces the problem

https://phpstan.org/r/64f8d2c8-343a-44ca-bbde-60e8162bd3b9

Expected output

I would expect the parameter type would be narrowed.

function foo(Entity1|Entity2 $entity): void
{
	$entity->setFoo(null); // This should cause an error: Parameter #1 $foo of method Entity1::setFoo() expects string, null given.
}

Did PHPStan help you today? Did it make you happy in any way?

PHPStan has become completely ingrained in my workflow. I'm always surprised when it doesn't catch a bug in my code!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions