Use of instanceof does not infer correct intersection type
Closed this issue ยท 5 comments
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: phpstan/phpstan-phpunit#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.