loophp / collection

A (memory) friendly, easy, lazy and modular collection class.
https://loophp-collection.rtfd.io/
MIT License
721 stars 35 forks source link

Palm cannot infer types when using some operations #318

Closed Matth-- closed 10 months ago

Matth-- commented 11 months ago

Steps required to reproduce the problem

/** @psalm-trace $test */
$test = Collection::fromIterable(self::cases())
    ->associate(
        fn (int $key, ApplicationGrade $grade) => $grade->value,
        fn (ApplicationGrade $grade) => sprintf('%d - %s', $grade->value, self::transformKey($grade->name))
    )->all();

This trace results in psalm reporting the following

psalm: MixedAssignment: Unable to determine the type that $test is being assigned to

Steps for normal type inference

If I do normalize first it is able to infer the type

/** @psalm-trace $test2 */
$test2 = Collection::fromIterable(self::cases())
    ->normalize()
    ->associate(
        fn(int $key, ApplicationGrade $grade) => $grade->value,
        fn(ApplicationGrade $grade) => sprintf('%d - %s', $grade->value, self::transformKey($grade->name))
    );

The result is

psalm: Trace: $test2: loophp\collection\Contract\Collection<1|2|3|4|5, non-empty-string>

Actual fix

If i change the @return annotation to one of the following examples it works

/**
 * @template UKey
 * @template U
 *
 * @param iterable<UKey, U> $iterable
 *
 * //THIS WORKS
 * @return CollectionInterface<UKey, U>&self<UKey, U>
 * @return CollectionInterface<UKey, U>
 * 
 * //THIS DOES NOT WORK
 * @return self<UKey, U>
 */
public static function fromIterable(iterable $iterable): CollectionInterface
{
    return new self(static fn (): Generator => yield from new IterableIteratorAggregate($iterable));
}

Question

I'm happy to open a pull request but wanted to know what is preferred to do here. It might be that a fix is needed in Psalm (not familiar with that codebase). PHPStan does not seem to have any issues with the examples above and the fix does not seem to break PHPStan

drupol commented 11 months ago

Hi!

Yes please open a PR and let's discuss your changes in there.

Thanks !

github-actions[bot] commented 10 months ago

Since this issue has not had any activity within the last 5 days, I have marked it as stale. I will close it if no further activity occurs within the next 5 days.

drupol commented 10 months ago

Dear @Matth--,

Is it OK with opening the PR ? Do you need some assistance?

Matth-- commented 10 months ago

Hi @drupol

Yep sorry started last week but had to look into how to configure psalm to report the issue first. 😄