phptools-docs icon indicating copy to clipboard operation
phptools-docs copied to clipboard

Bogus error "Cannot implicitly convert 'void' to 'string'"

Open php4fan opened this issue 11 months ago • 11 comments

I'm getting this bogus error in the IDE from this fragment of code:

image

image

"Cannot implicitly convert 'void' to 'string'"

In reality the code runs and always works as expected.

Even if I replace the first line:

$codes = $this->getNewPromoCodes($n);

with this:

$codes = [];

which means that the body of the foreach loop would never run, I still get the error!!

I have not been able to reproduce with minimal code.

php4fan avatar Dec 29 '24 16:12 php4fan

I have found a minimal example that reproduces the issue:

<?php

class TestClass {
    public function doTest() {
        $codes = [];

        foreach ($codes as $code) {
            echo "Foo bar $code";
        }
    }
}

The exact same code outside of a class method does not reproduce:

$codes = [];

foreach ($codes as $code) {
    echo "Foo bar $code";
}

php4fan avatar Dec 29 '24 17:12 php4fan

@php4fan thank you for the test case. I think this is regression.

jakubmisek avatar Dec 30 '24 14:12 jakubmisek

Still getting this annoying issue.

php4fan avatar Feb 10 '25 17:02 php4fan

@php4fan thank you for reminding me.

We'll suppress the warning.

What's the return value of $this->getNewPromoCodes() ? It looks like the editor thinks it returns an empty array.

jakubmisek avatar Feb 10 '25 17:02 jakubmisek

It can indeed return an empty array, but that shouldn't be an issue since in that case the foreach loop won't run at all.

When it's not empty, it's an array of strings.

This is the code:

public function getNewPromoCodes($n = 1) {
        $codes = [];
        for ($i = 0; $i < 1000 && count($codes) < $n; $i++) {
            $new_codes = [];
            for ($k = 0; $k < $n - count($codes); $k++) {
                $newcode = $this->generateRandomPromoCode();
                if (in_array($newcode, $codes)) continue;
                $new_codes[$newcode] = true;
            }
            $existing = $this->query_all(
                "
                    SELECT * FROM `{BOT_TABLE}promo_code`
                    WHERE code IN(:codes)
                ", 
                ['codes' => array_keys($new_codes)],
                ['codes' => Connection::PARAM_STR_ARRAY]
            );
            foreach($existing as $ecode) {
                unset($new_codes[$ecode['code']]);
            }
            $codes = array_merge($codes, array_keys($new_codes));
        }
        return $codes;
    }

    public function generateRandomPromoCode() {
        $chars = "abcdefghijklmnop" .
                 "qrstuvwxyzABCDEF" .
                 "GHIJKLMNOPQRSTUV" .
                 "WXYZ0123456789-_";
        $output = "";
        for ($i = 0; $i < 16; $i++) {
            $output .= $chars[random_int(0, 63)];
        }
        return $output;
    }

$this->query_all() is a wrapper around Doctrine\DBAL\Connection::fetchAllAssociative().

php4fan avatar Feb 10 '25 18:02 php4fan

Note the trivial example in #issuecomment-2564782562

php4fan avatar Feb 10 '25 18:02 php4fan

Thank you for pointing this out.

The void->string warning has been fixed.

I think the cause of most of these issues is the array sometimes being treated as empty [], which causes foreach to iterate over void values (doesn't matter - it's our problem).

In general a doc comment like /** @return string[] */ or a return type hint would help a lot.

jakubmisek avatar Feb 17 '25 15:02 jakubmisek

I'm building a WordPress plugin and receiving a lot of this error, specifically when trying to use ACF functions. I installed the acf stubs:

Image

and added to the include path:

Image

but still receiving this:

Image

When I "Go to definition" or "Peek definition" I see the correct definition, so where is it pulling the incorrect one from?

Is there a way to re-index the definitions?

jackskaret-aimclear avatar Mar 11 '25 15:03 jackskaret-aimclear

@jackskaret-aimclear it looks like we don't recognize the @return annotation (because the author of those stubs uses incorrect /* comment type, it should be /**)

Also, "php.workspace.includePath" is unnecessary in this case. It makes the extension run only slower.

jakubmisek avatar Mar 11 '25 15:03 jakubmisek

Thank you! That fixed it.

RE:includePath - I figured it wasn't necessary, just a troubleshooting step.

jackskaret-aimclear avatar Mar 11 '25 15:03 jackskaret-aimclear

@jackskaret-aimclear maybe we should give pull request to https://github.com/kimhf/advanced-custom-fields-stubs/blob/c3b34a01faf724aeb29d62620fb328f420a2f851/advanced-custom-fields-stubs.php#L14112 to change /* to /**

jakubmisek avatar Mar 11 '25 15:03 jakubmisek