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

Type confusion regression from #9373 #9968

Closed
lstrojny opened this issue Jun 27, 2023 · 3 comments · Fixed by #9988
Closed

Type confusion regression from #9373 #9968

lstrojny opened this issue Jun 27, 2023 · 3 comments · Fixed by #9988

Comments

@lstrojny
Copy link
Contributor

Introduced in ad5bf62

Before: no error

After:

ERROR: MixedArgument - src/Builder/FilterBuilder.php:30:36 - Argument 1 of preg_replace cannot be mixed, expecting array<array-key, string>|string (see https://psalm.dev/030)
        $harmonized = preg_replace(self::ANY_NEWLINE, Newline::UNIX->value, $text);

It’s pretty hard to build a minimal reproduction case because it seems to be only happening if autoloading is involved. So I stripped down the library to a minimal reproduction case and this is the branch: https://github.com/lstrojny/uffff/tree/dev/psalm-bug-repro

It only consists of two files:

src/Builder/FilterBuilder.php

<?php

namespace Uffff\Builder;

class FilterBuilder
{
    /**
     * @return callable(string):string
     */
    public function build(): callable
    {
        return static fn(string $v) => $v;
    }
}

enum Newline: string
{
    case UNIX = "\n";
    case WINDOWS = "\r\n";
    case MAC = "\r";
}

class HarmonizeNewlines
{
    // Order matters, Windows must come first
    private const ANY_NEWLINE = '/(?:' . Newline::WINDOWS->value . '|' . Newline::MAC->value . '|' . Newline::UNIX->value . ')/';

    public function __invoke(string $text): string
    {
        $harmonized = preg_replace(self::ANY_NEWLINE, Newline::UNIX->value, $text);

        assert(is_string($harmonized));

        return $harmonized;
    }
}

src/functions.php:

<?php

declare(strict_types=1);

namespace Foo;

use Uffff\Builder\FilterBuilder;

function unicode(string $text): string
{
    $filter = (new FilterBuilder())->build();

    return $filter($text);
}

The two files are covered by composer autoloading like this:

    "autoload": {
        "psr-4": {
            "Uffff\\": "src/"
        },
        "files": [
            "src/functions.php"
        ]
    },

The issue does not happen if:

  • The namespace changes
  • The FilterBuilder is removed and instead we try to use HarmonizeNewlines directly in functions.php
@psalm-github-bot
Copy link

Hey @lstrojny, can you reproduce the issue on https://psalm.dev ?

@ygottschalk
Copy link
Contributor

If not solved until then, I will be looking at this at the weekend

@lstrojny
Copy link
Contributor Author

@ygottschalk thank you

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

Successfully merging a pull request may close this issue.

2 participants