Bug report
When having a function with a union of (constant) strings as argument and a second parameter for which the type depends on the other argument one could use a conditional parameter type (@param ($param1 is 'foo' ? int : bool) $param2). This only seems to happen when the union type consists of more than 2 types. This as, as far as I tried to debug it and understood the code, the conditional parameter type is split in two ConditionalExpressionHolders, one for the true condition and one for the false condition. These conditions are based on TypeCombinator::intersect and TypeCombinator::remove where supplied arguments are the type of the argument the condition is compared too and the supplied condition type. For the supplied example this thus leads to two ConditionalExpressionHolders, one of ConstantStringType('value3') which results in a boolean and one of UnionType([ConstantStringType('value1'), ConstantStringType('value2')]) which results in a integer.
Later on when the these conditional expressions are tested. But in this case for the match arms / conditions on 'value1' and 'value2' these comparisons fail. This as the ConstantStringType (containing the value1 / value2 as value) are tested for equality against the UnionType which fails.
There are also scenario's which result in other (un)expected results. In case where $param1 consists only of 2 types ('value1'|'value2', without |'value3') it always seems to work fine for example, as in that case the TypeCombinator::intersect and TypeCombinator::remove calls both result in a ConstantStringType which will obviously be fine for the comparison. But when changing the order of the match arms, so 'value3' is the first condition it also works fine.
Code snippet that reproduces the problem
https://phpstan.org/r/5b254792-1ecd-49ed-a140-930184c7a820
Expected output
No errors.
And applying \PHPStan\dumpType($param2) in the match arms should thus result in: value1 => int, value2 => int, value3 => bool.
Did PHPStan help you today? Did it make you happy in any way?
No response
Bug report
When having a function with a union of (constant) strings as argument and a second parameter for which the type depends on the other argument one could use a conditional parameter type (
@param ($param1 is 'foo' ? int : bool) $param2). This only seems to happen when the union type consists of more than 2 types. This as, as far as I tried to debug it and understood the code, the conditional parameter type is split in twoConditionalExpressionHolders, one for the true condition and one for the false condition. These conditions are based onTypeCombinator::intersectandTypeCombinator::removewhere supplied arguments are the type of the argument the condition is compared too and the supplied condition type. For the supplied example this thus leads to twoConditionalExpressionHolders, one ofConstantStringType('value3')which results in a boolean and one ofUnionType([ConstantStringType('value1'), ConstantStringType('value2')])which results in a integer.Later on when the these conditional expressions are tested. But in this case for the match arms / conditions on
'value1'and'value2'these comparisons fail. This as theConstantStringType(containing thevalue1/value2as value) are tested for equality against theUnionTypewhich fails.There are also scenario's which result in other (un)expected results. In case where
$param1consists only of 2 types ('value1'|'value2', without|'value3') it always seems to work fine for example, as in that case theTypeCombinator::intersectandTypeCombinator::removecalls both result in aConstantStringTypewhich will obviously be fine for the comparison. But when changing the order of the match arms, so'value3'is the first condition it also works fine.Code snippet that reproduces the problem
https://phpstan.org/r/5b254792-1ecd-49ed-a140-930184c7a820
Expected output
No errors.
And applying
\PHPStan\dumpType($param2)in the match arms should thus result in: value1 => int, value2 => int, value3 => bool.Did PHPStan help you today? Did it make you happy in any way?
No response