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

Hanging when using a big case statement of constants in a foreach $key => $value #9926

Closed
jeremy-smith-maco opened this issue Jun 19, 2023 · 5 comments · Fixed by #9929
Closed

Comments

@jeremy-smith-maco
Copy link

jeremy-smith-maco commented Jun 19, 2023

When looping over an array using foreach ($array as $key => $value) with a large case statement of constants it seems to hang for a long time. Might be something related to #6741 or maybe not but it was the closest issue I could find to this.

It works fine for scalar values like strings, break the number of cases up into smaller blocks and also works if you're looping over values using foreach ($array as $value) but not in this case.

I have a reproduction case: https://psalm.dev/r/4d3d94a149

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/4d3d94a149
<?php

class A
{
    const CONST_0000 = 0;
    const CONST_0001 = 1;
    const CONST_0002 = 2;
    const CONST_0003 = 3;
    const CONST_0004 = 4;
    const CONST_0005 = 5;
    const CONST_0006 = 6;
    const CONST_0007 = 7;
    const CONST_0008 = 8;
    const CONST_0009 = 9;
    const CONST_0010 = 10;
    const CONST_0011 = 11;
    const CONST_0012 = 12;
    const CONST_0013 = 13;
    const CONST_0014 = 14;
    const CONST_0015 = 15;
    const CONST_0016 = 16;
    const CONST_0017 = 17;
    const CONST_0018 = 18;
    const CONST_0019 = 19;
    const CONST_0020 = 20;
    const CONST_0021 = 21;
    const CONST_0022 = 22;
    const CONST_0023 = 23;
    const CONST_0024 = 24;
    const CONST_0025 = 25;
    const CONST_0026 = 26;
    const CONST_0027 = 27;
    const CONST_0028 = 28;
    const CONST_0029 = 29;
    const CONST_0030 = 30;

    public function testSomething(array $array): string
    {
        foreach ($array as $key => $value)
        {
            switch ($key) {
                case self::CONST_0000:
                case self::CONST_0001:
                case self::CONST_0002:
                case self::CONST_0003:
                case self::CONST_0004:
                case self::CONST_0005:
                case self::CONST_0006:
                case self::CONST_0007:
                case self::CONST_0008:
                case self::CONST_0009:
                case self::CONST_0010:
                case self::CONST_0011:
                case self::CONST_0012:
                case self::CONST_0013:
                case self::CONST_0014:
                case self::CONST_0015:
                case self::CONST_0016:
                case self::CONST_0017:
                case self::CONST_0018:
                case self::CONST_0019:
                case self::CONST_0020:
                case self::CONST_0021:
                case self::CONST_0022:
                case self::CONST_0023:
                case self::CONST_0024:
                case self::CONST_0025:
                case self::CONST_0026:
                case self::CONST_0027:
                case self::CONST_0028:
                case self::CONST_0029:
                case self::CONST_0030:
                    return 'found';
            }
        }
        
        return 'not found';
    }
}
Psalm output (using commit 2e8d575):

INFO: MixedAssignment - 39:36 - Unable to determine the type that $value is being assigned to

INFO: UnusedForeachValue - 39:36 - $value is never referenced or the value is not used

INFO: UnusedClass - 3:7 - Class A is never used

@orklah
Copy link
Collaborator

orklah commented Jun 19, 2023

Reproducible without the foreach: https://psalm.dev/r/cbaddaa911

Switch resolution is a big performance hog in Psalm

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/cbaddaa911
<?php

class A
{
    const CONST_0000 = 0;
    const CONST_0001 = 1;
    const CONST_0002 = 2;
    const CONST_0003 = 3;
    const CONST_0004 = 4;
    const CONST_0005 = 5;
    const CONST_0006 = 6;
    const CONST_0007 = 7;
    const CONST_0008 = 8;
    const CONST_0009 = 9;
    const CONST_0010 = 10;
    const CONST_0011 = 11;
    const CONST_0012 = 12;
    const CONST_0013 = 13;
    const CONST_0014 = 14;
    const CONST_0015 = 15;
    const CONST_0016 = 16;
    const CONST_0017 = 17;
    const CONST_0018 = 18;
    const CONST_0019 = 19;
    const CONST_0020 = 20;
    const CONST_0021 = 21;
    const CONST_0022 = 22;
    const CONST_0023 = 23;
    const CONST_0024 = 24;
    const CONST_0025 = 25;
    const CONST_0026 = 26;
    const CONST_0027 = 27;
    const CONST_0028 = 28;
    const CONST_0029 = 29;
    const CONST_0030 = 30;

    public function testSomething(string $key): string
    {
            switch ($key) {
                case self::CONST_0000:
                case self::CONST_0001:
                case self::CONST_0002:
                case self::CONST_0003:
                case self::CONST_0004:
                case self::CONST_0005:
                case self::CONST_0006:
                case self::CONST_0007:
                case self::CONST_0008:
                case self::CONST_0009:
                case self::CONST_0010:
                case self::CONST_0011:
                case self::CONST_0012:
                case self::CONST_0013:
                case self::CONST_0014:
                case self::CONST_0015:
                case self::CONST_0016:
                case self::CONST_0017:
                case self::CONST_0018:
                case self::CONST_0019:
                case self::CONST_0020:
                case self::CONST_0021:
                case self::CONST_0022:
                case self::CONST_0023:
                case self::CONST_0024:
                case self::CONST_0025:
                case self::CONST_0026:
                case self::CONST_0027:
                case self::CONST_0028:
                case self::CONST_0029:
                case self::CONST_0030:
                    return 'found';
            }
        
        return 'not found';
    }
}
Psalm output (using commit 2e8d575):

INFO: UnusedClass - 3:7 - Class A is never used

@orklah
Copy link
Collaborator

orklah commented Jun 19, 2023

it's now almost instantaneous :)

@jeremy-smith-maco
Copy link
Author

Thank you so much for your swift response and fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants