phpstan icon indicating copy to clipboard operation
phpstan copied to clipboard

Array shape intersection incorrect when a value is a union of constants

Open lkrms opened this issue 1 year ago • 7 comments
trafficstars

Bug report

The examples below are derived from code where this issue surfaced for me and may be more complicated than necessary.

This works because the array shapes in question have an int at index 0: https://phpstan.org/r/b065b44f-5f92-4462-a5ca-b5d312280772

But when the value at index 0 is 0|1|2|3, int leaks into the resolved type of the adjacent value:

Code snippet that reproduces the problem

https://phpstan.org/r/edd0a6b2-b1f7-452a-88c2-8a9342e91781

Expected output

The intersection of array{0|1|2|3, int|Payload|string|null} and array{0|1|2|3, Payload} should be array{0|1|2|3, Payload}, not array{0|1|2|3, int|Payload}

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

No response

lkrms avatar Jun 25 '24 13:06 lkrms

I made some comments to make the problem more obvious: https://phpstan.org/r/78fb6f20-fa82-40cc-bcf5-fbd8c3dafad0 and I agree, this is a bug.

But I don't understand what's happening with TInput&T0. Because if I didn't overlook something, that's Payload&(0|1|2|3) and that really doesn't make sense.

ondrejmirtes avatar Jun 25 '24 13:06 ondrejmirtes

Sorry, I'm on the wrong device to update the test, but T0=0|1|2|3 is incorrect; T0 is Payload in this case.

lkrms avatar Jun 26 '24 09:06 lkrms

Alright, fixed example: https://phpstan.org/r/a983ae46-0e54-4e0b-ae24-d7b10c9a7936

ondrejmirtes avatar Jun 26 '24 09:06 ondrejmirtes

@lkrms After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:

@@ @@
-52: Dumped type: Pipeline<Payload, array, array{int, int|Payload|string|null}>
+52: Dumped type: Pipeline<Payload, array<mixed>, array{int, int|Payload|string|null}>
 53: Dumped type: array{int, Payload}
-54: Dumped type: Pipeline<Payload, array, array{int, Payload}>
+54: Dumped type: Pipeline<Payload, array<mixed>, array{int, Payload}>
Full report
Line Error
52 `Dumped type: Pipeline<Payload, array, array{int, int
53 Dumped type: array{int, Payload}
54 Dumped type: Pipeline<Payload, array<mixed>, array{int, Payload}>

phpstan-bot avatar Oct 12 '24 15:10 phpstan-bot

@lkrms After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:

@@ @@
-53: Dumped type: Pipeline<Payload, array, array{0|1|2|3, int|Payload|string|null}>
+53: Dumped type: Pipeline<Payload, array<mixed>, array{0|1|2|3, int|Payload|string|null}>
 54: Dumped type: array{0|1|2|3, Payload}
-55: Dumped type: Pipeline<Payload, array, array{0|1|2|3, int|Payload}>
+55: Dumped type: Pipeline<Payload, array<mixed>, array{0|1|2|3, int|Payload}>
Full report
Line Error
53 `Dumped type: Pipeline<Payload, array, array{0
54 `Dumped type: array{0
55 `Dumped type: Pipeline<Payload, array, array{0

phpstan-bot avatar Oct 12 '24 15:10 phpstan-bot

@ondrejmirtes After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:

@@ @@
-53: Dumped type: Pipeline<Payload, array, array{0|1|2|3, int|Payload|string|null}>
+53: Dumped type: Pipeline<Payload, array<mixed>, array{0|1|2|3, int|Payload|string|null}>
 54: Dumped type: array{0|1|2|3, Payload}
-64: Dumped type: Pipeline<Payload, array, array{0|1|2|3, int|Payload}>
+64: Dumped type: Pipeline<Payload, array<mixed>, array{0|1|2|3, int|Payload}>
Full report
Line Error
53 `Dumped type: Pipeline<Payload, array, array{0
54 `Dumped type: array{0
64 `Dumped type: Pipeline<Payload, array, array{0

phpstan-bot avatar Oct 12 '24 15:10 phpstan-bot

@ondrejmirtes After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:

@@ @@
-53: Dumped type: Pipeline<Payload, array, array{0|1|2|3, int|Payload|string|null}>
+53: Dumped type: Pipeline<Payload, array<mixed>, array{0|1|2|3, int|Payload|string|null}>
 54: Dumped type: array{0|1|2|3, Payload}
-64: Dumped type: Pipeline<Payload, array, array{0|1|2|3, int|Payload}>
+64: Dumped type: Pipeline<Payload, array<mixed>, array{0|1|2|3, int|Payload}>
Full report
Line Error
53 `Dumped type: Pipeline<Payload, array, array{0
54 `Dumped type: array{0
64 `Dumped type: Pipeline<Payload, array, array{0

phpstan-bot avatar Oct 12 '24 15:10 phpstan-bot