Skip to content

array_is_list result are wrong when playing with unset. #11628

@VincentLanglet

Description

@VincentLanglet

Bug report

I tried a PR to fix it (phpstan/phpstan-src#3400) but currently I'm stuck with the fix and dunno if it doesn't imply biggest changes about how PHPStan deals with list... so I prefer to discuss about this issue with you @ondrejmirtes first.

It may be surprising but the code

$a = [1, 2, 3];
unset($a[2]);

var_dump(array_is_list($a));

display TRUE. See https://3v4l.org/XX2fU

The php method only checks the array key, and not the next array key.
Which also means unsetting a value to a non-list might give a list. (cf example)

So I'm not sure

  • If we have to "recompute" the isList property when unsetting a value (and how ?)
  • If the isList method should become dynamic instead of relying on a static property, with an implementation like:
			$this->isList = TrinaryLogic::createYes();

			foreach ($this->keyTypes as $i => $keyType) {
				$this->isList->and((new ConstantIntegerType($i))->isSuperTypeOf($keyType));
			}

			$optionalKeyNumber = count($this->optionalKeys);
			if (
				($optionalKeyNumber > 1)
				|| ($optionalKeyNumber === 1 && !$this->isOptionalKey(count($this->keyTypes) - 1))
			) {
				$this->isList->and(TrinaryLogic::createMaybe());
			}
  • If we should just ignore the case a non-list become a list, and fix the case where we unset the last element
  • If we should just ignore both case and close the issue (?)

Code snippet that reproduces the problem

https://phpstan.org/r/7b40683e-010c-4d5a-96dc-9fda4ce27797

Expected output

First call will always evaluate to true.
Second call will always evaluate to false.
Third call will always evaluate to true.

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

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions