You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
in_array() narrowing drops the list flag from a list shape with optional keys (regression in 2.1.41) #15391
When in_array() narrows a list{...} shape that has two or more optional keys, the narrowed type loses the list flag and becomes array{...}. A narrowed list is still a list, and the result should be a subtype of the original list{...} type. In practice this gives false return.type errors for list<T> return types.
Since that commit, a list{...} shape is a ConstantArrayType with the list flag set (makeList()), and no longer an intersection with AccessoryArrayListType. TypeCombinator::intersect() handles a constant array and an ArrayType by rebuilding the shape with ConstantArrayTypeBuilder (TypeCombinator.php#L2263-L2312). With optional keys, the builder can only mark the result as "maybe a list" (ConstantArrayTypeBuilder.php#L246-L254), so the flag of the original list is lost.
With bleeding edge in 2.3.0 the same loss also shows when a closure appends to a use (&$list) array, because phpstan/phpstan-src#6610 now applies the closure body where the closure is called. That is how we found it.
Activity
Rename regression test to bug-15391