phpstan
phpstan copied to clipboard
Use of instanceof does not infer correct intersection type
Bug report
If I have a property of type class-string<Model&One&Two&Three> and try to assign a class string of a Model that has previously been checked if it as instance of One, Two and Three, phpstan reports the type for the Model to be class-string<Model>&class-string<One>&class-string<Three>&class-string<Two>.
Code snippet that reproduces the problem
https://phpstan.org/r/d90507d3-8e31-456b-85fe-56e9571aabc6
Expected output
I would expect the outcome to be class-string<Model&One&Two&Three> instead of class-string<Model>&class-string<One>&class-string<Three>&class-string<Two>.
I also had a variation of this reporting where the code is practically the same, but phpstan inferred the type class-string<Model>|class-string<One>|class-string<Three>|class-string<Two> instead. I cannot tell why the playground gives a different result - but both results appear wrong to me.
Possibly related: https://github.com/phpstan/phpstan-phpunit/issues/131
@lupinitylabs After the latest push in 1.8.x, PHPStan now reports different result with your code snippet:
@@ @@
PHP 8.0 – 8.1 (1 error)
==========
-11: Property HelloWorld::$class (class-string<Model&One&Three&Two>|null) does not accept class-string<Model>&class-string<One>&class-string<Three>&class-string<Two>.
+11: Property HelloWorld::$class (class-string<Model&One&Three&Two>|null) does not accept class-string<Model&One&Three&Two>|(class-string<Model>&class-string<One>&class-string<Three>&class-string<Two>).
PHP 7.1 – 7.4 (3 errors)
==========
@@ @@
8: Promoted properties are supported only on PHP 8.0 and later.
11: Accessing ::class constant on an expression is supported only on PHP 8.0 and later.
-11: Property HelloWorld::$class (class-string<Model&One&Three&Two>|null) does not accept class-string<Model>&class-string<One>&class-string<Three>&class-string<Two>.
+11: Property HelloWorld::$class (class-string<Model&One&Three&Two>|null) does not accept class-string<Model&One&Three&Two>|(class-string<Model>&class-string<One>&class-string<Three>&class-string<Two>).
Full report
PHP 8.0 – 8.1 (1 error)
| Line | Error |
|---|---|
| 11 | `Property HelloWorld::$class (class-string<Model&One&Three&Two> |
PHP 7.1 – 7.4 (3 errors)
| Line | Error |
|---|---|
| 8 | Promoted properties are supported only on PHP 8.0 and later. |
| 11 | Accessing ::class constant on an expression is supported only on PHP 8.0 and later. |
| 11 | `Property HelloWorld::$class (class-string<Model&One&Three&Two> |
@lupinitylabs After the latest push in 1.8.x, PHPStan now reports different result with your code snippet:
@@ @@
-PHP 8.0 – 8.1 (1 error)
+PHP 8.0 – 8.1
==========
-11: Property HelloWorld::$class (class-string<Model&One&Three&Two>|null) does not accept class-string<Model>&class-string<One>&class-string<Three>&class-string<Two>.
+No errors
-PHP 7.1 – 7.4 (3 errors)
+PHP 7.1 – 7.4 (2 errors)
==========
8: Promoted properties are supported only on PHP 8.0 and later.
-11: Accessing ::class constant on an expression is supported only on PHP 8.0 and later.
-11: Property HelloWorld::$class (class-string<Model&One&Three&Two>|null) does not accept class-string<Model>&class-string<One>&class-string<Three>&class-string<Two>.
+11: Accessing ::class constant on an expression is supported only on PHP 8.0 and later.
Full report
PHP 8.0 – 8.1
No errors
PHP 7.1 – 7.4 (2 errors)
| Line | Error |
|---|---|
| 8 | Promoted properties are supported only on PHP 8.0 and later. |
| 11 | Accessing ::class constant on an expression is supported only on PHP 8.0 and later. |
/cc @rvanvelzen Regression test please :)
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.