Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] "Method…should return Generator but returns false" #574

Closed
mfn opened this issue Nov 1, 2017 · 7 comments
Closed

[BUG] "Method…should return Generator but returns false" #574

mfn opened this issue Nov 1, 2017 · 7 comments

Comments

@mfn
Copy link

mfn commented Nov 1, 2017

This is a false positive, because returning false from a method which yields still returns a Generator, see:

<?php

function foo(): Generator
{
    return false;
    yield "yolo";
}

var_dump(foo());

Output:

object(Generator)#1 (0) { }

See also https://3v4l.org/VcSpa

@ondrejmirtes
Copy link
Member

I don't understand, what is a real-world usecase for this?

@tsufeki
Copy link

tsufeki commented Nov 1, 2017

@ondrejmirtes
Copy link
Member

OK, my proposed fix is:

  1. Turn off ReturnTypeRule for generator functions.
  2. Get "custom node visitors" implemented - this is a feature that will allow efficient rules implementation for advanced stuff that depends on multiple nodes - for example, right now PHPStan does not complain about methods that should return something but do not contain return at all.
  3. Write a special rule that will get executed only on generator functions and will look for an existing yield in the body.

@ondrejmirtes
Copy link
Member

Implemented first part: 5b940d5

@muglug
Copy link
Contributor

muglug commented Jul 15, 2018

More examples: https://phpstan.org/r/da276b35474dead2cfa290e8d6b96ff1

function f() : Generator {
    yield 1;
    yield 2;
    return "hello";
}

function g() : Generator {
    if (rand(0, 1)) {
        return;
    }

    if (rand(0, 1)) {
        yield 1;
    }

    return "goodbye";
}

$f = f();
$g = g();

foreach ($f as $i) {
    var_dump($i);
}
var_dump($f->getReturn());

foreach ($g as $j) {
    var_dump($j);
}
var_dump($g->getReturn());

@muglug
Copy link
Contributor

muglug commented Jul 15, 2018

But the second option here should fail as in https://getpsalm.org/r/0ef6ef4478

function generator2() : Generator {
    if (rand(0,1)) {
        return;
    }
    yield 2;
}

function notagenerator() : Generator {
    if (rand(0,1)) {
        return;
    }
    return generator2();
}

@ondrejmirtes
Copy link
Member

This already works, thanks.

@lock lock bot locked as resolved and limited conversation to collaborators Dec 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants