Skip to content

List type changed to list<*ERROR*> when list changed inside loop #13385

@LastDragon-ru

Description

@LastDragon-ru

Bug report

As you can see, all vars are inferred correctly, but after $operands[] = $value; the type of $operands unexpectedly changed to list<*ERROR*>

/**
	 * @param list<Operator|int> $children
	 */
	public function calculate(array $children): int {
        $operands  = [];
        $operators = [];

        foreach ($children as $child) {  
            if ($child instanceof Operator) {
                while ($operators !== [] && end($operators)->priority() >= $child->priority()) {
                    $op    = array_pop($operators);
                    $left  = array_pop($operands) ?? 0;
                    $right = array_pop($operands) ?? 0;

					assert(is_int($left));
					assert(is_int($right));
					
                    $value = $op->calculate($left, $right);

					dumpType($op);    // ok, Dumped type: Operator
					dumpType($left);  // ok, Dumped type: int
					dumpType($right); // ok, Dumped type: int
					dumpType($value); // (!) ok, Dumped type: int
					
                    $operands[] = $value;

					dumpType($operands); // (!!!) non-empty-list<*ERROR*>
                }

                $operators[] = $child;
            } else {
                $operands[] = $child;
            }
        }


        return count($operands) === 1 ? reset($operands) : 0;
    }

Code snippet that reproduces the problem

https://phpstan.org/r/4ca28bb7-a9ce-4085-9858-890965a39bc7

Expected output

list<int>

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

Yep, helps a lot every day)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions