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

reproduce specifier bug

Open staabm opened this issue 3 years ago • 9 comments

with https://github.com/phpstan/phpstan-src/pull/1383/files#r887647098 I was running into this bug.

the problem is, that phpstan should dump the type string but reports bool|float|int|string for the dumpType call seen here:

$ php bin/phpstan analyze src/Analyser/TypeSpecifier.php
Note: Using configuration file C:\dvl\Workspace\phpstan-src-staabm\phpstan.neon.dist.
 1/1 [============================] 100%

 ------ ------------------------------------
  Line   TypeSpecifier.php
 ------ ------------------------------------
  274    Dumped type: bool|float|int|string
 ------ ------------------------------------

I am not yet sure how to debug this issue further. I also tried reproducing the case in a smaler repro script, but this did not work out yet.

any ideas/hints?

staabm avatar Jun 03 '22 14:06 staabm

I guess I'd try using xdebug here, in case you didn't do that already.

herndlm avatar Jun 03 '22 20:06 herndlm

I tried, but wasn't sure where to look tbh

staabm avatar Jun 03 '22 20:06 staabm

after a bit more trying, I was able to reduce the repro further

this PR now includes a proper NodeScopeResolverTest for the problem

staabm avatar Jun 04 '22 07:06 staabm

Check this strange behavior as well:

  • https://phpstan.org/r/889e3c66-972b-4ace-af00-e9beb3280918 (with dumpType($constantType))
  • https://phpstan.org/r/1e85e658-425f-44ef-afeb-7243c3df5221 (without dumpType($constantType))

rvanvelzen avatar Jun 09 '22 14:06 rvanvelzen

@rvanvelzen @rajyan might one of you guys has time to look into this problem?

staabm avatar Jul 07 '22 15:07 staabm

I've looked into this recently but it didn't look trivial to solve. I'm a bit swamped at work right now but I'll look into it more when that settles down again :)

rvanvelzen avatar Jul 07 '22 16:07 rvanvelzen

@staabm This was harder to solve than I thought. You can see https://github.com/phpstan/phpstan-src/pull/1495 when $var is specified, you might narrow down $var->call() more. In this case, $var->call() is specified as non-null at first, and the next instanceof ConstantString type can specify $var->call() more. Currently, these types of type specification is not handled.

rajyan avatar Jul 08 '22 14:07 rajyan

after working thru this I implemented several different solutions, which made the test pass, but regressed other things.

by doing this I got a better understanding how things work and how a possible solution could look like.

atm I think we need to adjust this block: https://github.com/phpstan/phpstan-src/blob/b0babd082514303ec62deb5f16cf330f845c1821/src/Analyser/MutatingScope.php#L3551-L3579

.. so it takes into account when a variable get specified to a new ObjectType - e.g. via $constantType instanceof ConstantStringType. We need to update all moreSpecificTypeHolders which depend on $constantType , e.g. $constantType->getValue() and merge the existing type of $constantType->getValue() with the new knowledge that $var was specified to ConstantStringType and therefore we have a better idea of $constantType->getValue().

class HelloWorld
{
	public function doFoo(
		ConstantScalarType $constantType
	)
	{
		if ($constantType->getValue() === null) {
			return;
		}
		assertType('bool|float|int|string', $constantType->getValue());

		if (
			$constantType instanceof ConstantStringType
		) {
			assertType('string', $constantType->getValue());
		}
	}
}

in the end I think this is a similar thing, this line achieves for array-offset-types: https://github.com/phpstan/phpstan-src/blob/b0babd082514303ec62deb5f16cf330f845c1821/src/Analyser/MutatingScope.php#L3577

staabm avatar Sep 23 '22 08:09 staabm

finally, this one is ready for review.

staabm avatar Sep 23 '22 10:09 staabm

Is this still a problem?

ondrejmirtes avatar Oct 16 '22 09:10 ondrejmirtes

The underlying bug should still be present, but in phpstan-src I worked arround it in a related PR, so the phpstan-src codebase is no longer blocked by it right now

staabm avatar Oct 16 '22 10:10 staabm

It'd be better to reproduce this on phpstan.org/try and open an issue.

ondrejmirtes avatar Oct 23 '23 21:10 ondrejmirtes