noverify icon indicating copy to clipboard operation
noverify copied to clipboard

Wrong "array access to non-array type" message

Open vbifial opened this issue 4 years ago • 3 comments

Code Example

<?php
class Reader
{
}

class MWorker
{
    /**
     * @param string $type
     * @return Reader|array
     */
    public function getData($type)
    {
        if ($type == 'array') {
            return [];
        }
        return new Reader();
    }
}

class Manager
{
    /**
     * @var MWorker
     */
    private $worker;

    /**
     * @return Reader
     */
    public function getReader()
    {
        return $this->worker->getData('reader');
    }

    /**
     * @return array
     */
    public function getArray()
    {
        return $this->worker->getData('array');
    }
}

class Service
{
    public function run()
    {
        $manager = new Manager();
        $a = $manager->getArray();
        echo $a['myIndex'];
    }
}

Actual Behavior

MAYBE   arrayAccess: Array access to non-array type \Reader|mixed[] at Sample.php:51
        echo $a['myIndex'];
             ^^

Expected Behavior

No warnings

vbifial avatar Oct 07 '20 06:10 vbifial

Here Reader does not implement the ArrayAccess interface, so the error seems justified.

i582 avatar Oct 08 '20 10:10 i582

I redid your code a bit to get it running, we get an error as the Reader doesn't implement the ArrayAccess interface, so it doesn't seem like a linter error.

https://www.tehplayground.com/xUeHFrOt5ahF3zCT

Fatal error: Uncaught Error: Cannot use object of type Reader as array in Standard input code:55
Stack trace:
#0 Standard input code(60): Service->run()
#1 {main}
  thrown in Standard input code on line 55

i582 avatar Oct 08 '20 11:10 i582

@i582 The result of calling $manager->getArray() will always be array though, see the getData() code. In this case it actually is linter who is wrong.

I am not 100% sure why arrayAccess diagnostic demands that all types in a union must be arrays as it can be very tricky to figure out exact types sometimes. I would relax the check to only demand that at least one of the types is an array instead and it would solve the problem.

YuriyNasretdinov avatar Oct 08 '20 11:10 YuriyNasretdinov