phpstan-src icon indicating copy to clipboard operation
phpstan-src copied to clipboard

Fix MethodExistsTypeSpecifyingExtension for union types

Open staabm opened this issue 5 months ago • 4 comments

closes https://github.com/phpstan/phpstan/issues/13272

staabm avatar Jul 23 '25 08:07 staabm

This pull request has been marked as ready for review.

phpstan-bot avatar Jul 23 '25 09:07 phpstan-bot

@liamduckett I just realized that the fix of this PR produces a false-positive (see the newly added testcase). I do not yet know how to fix the initial problem without also regressing the other example.

just to let you know, as https://github.com/phpstan/phpstan-src/pull/4153 has the same problem

staabm avatar Jul 28 '25 06:07 staabm

@liamduckett I just realized that the fix of this PR produces a false-positive (see the newly added testcase). I do not yet know how to fix the initial problem without also regressing the other example.

just to let you know, as #4153 has the same problem

Thanks. I'm not sure I understand the new test case (probably due to my inexperience) - why would $bar being narrowed here, be a problem?

liamduckett avatar Jul 28 '25 19:07 liamduckett

the initial types were wrongly narrowed:

/**
 * @param 'quux'|'qux' $constUnion
 */
function fooBar(object $bar, string $constUnion): void
{
	if (!method_exists($bar, $constUnion)) {
		throw new \Exception;
	}

    // $bar does not have both methods, it has only either 'quux' or 'qux' but not both
}

while in the initial loop check example it is correct that $bar will have both methods at once:

foreach (['qux', 'quux'] as $method) {
		assertType("'quux'|'qux'", $method);

		if (!method_exists($bar, $method)) {
			throw new \Exception;
		}
}

staabm avatar Jul 29 '25 06:07 staabm