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

Invalid template instantiation for iterable #8124

Closed
klimick opened this issue Jun 17, 2022 · 5 comments · Fixed by #9660
Closed

Invalid template instantiation for iterable #8124

klimick opened this issue Jun 17, 2022 · 5 comments · Fixed by #9660

Comments

@klimick
Copy link
Contributor

klimick commented Jun 17, 2022

https://psalm.dev/r/6dbd395818 (array|Travesable against iterable)
https://psalm.dev/r/383c7f3677 simplified (only iterable)

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/6dbd395818
<?php

declare(strict_types=1);

/**
 * @return SplFixedArray<int>
 */
function getTraversable(): SplFixedArray
{
    return SplFixedArray::fromArray([1, 2, 3]);
}

/**
 * @return array<array-key, int>
 */
function getArray(): array
{
    return [1, 2, 3];
}

/**
 * @template A
 * @template B
 *
 * @param iterable<mixed, A> $lhs
 * @param iterable<mixed, B> $rhs
 * @return SplFixedArray<A|B>
 */
function mergeIterable(iterable $lhs, iterable $rhs): SplFixedArray
{
    return SplFixedArray::fromArray([...$lhs, ...$rhs]); 
}

/**
 * @template A
 * @template B
 *
 * @param array<array-key, A> $lhs
 * @param array<array-key, B> $rhs
 * @return SplFixedArray<A|B>
 */
function mergeArray(array $lhs, array $rhs): SplFixedArray
{
    return SplFixedArray::fromArray([...$lhs, ...$rhs]); 
}

/**
 * @template A
 * @template B
 *
 * @param Traversable<mixed, A> $lhs
 * @param Traversable<mixed, B> $rhs
 * @return SplFixedArray<A|B>
 */
function mergeTraversable(Traversable $lhs, Traversable $rhs): SplFixedArray
{
    return SplFixedArray::fromArray([...$lhs, ...$rhs]); 
}

// Works!
$_merged_traversable = mergeTraversable(getTraversable(), getTraversable());
/** @psalm-trace $_merged_traversable */;

// Works!
$_merged_array = mergeArray(getArray(), getArray());
/** @psalm-trace $_merged_array */;

// Don't :(
$_merged_iterable = mergeIterable(getTraversable(), getTraversable());
/** @psalm-trace $_merged_iterable */;
Psalm output (using commit 10ea05a):

INFO: Trace - 62:41 - $_merged_traversable: SplFixedArray<int>

INFO: Trace - 66:35 - $_merged_array: SplFixedArray<int>

INFO: Trace - 70:38 - $_merged_iterable: SplFixedArray<mixed>
https://psalm.dev/r/383c7f3677
<?php

declare(strict_types=1);

/**
 * @return SplFixedArray<int>
 */
function getTraversable(): SplFixedArray
{
    return SplFixedArray::fromArray([1, 2, 3]);
}

/**
 * @template A
 * @template B
 *
 * @param iterable<mixed, A> $lhs
 * @param iterable<mixed, B> $rhs
 * @return SplFixedArray<A|B>
 */
function mergeIterable(iterable $lhs, iterable $rhs): SplFixedArray
{
    return SplFixedArray::fromArray([...$lhs, ...$rhs]); 
}

// Expected SplFixedArray<int>, actual SplFixedArray<mixed>
$_merged_iterable = mergeIterable(getTraversable(), getTraversable());
/** @psalm-trace $_merged_iterable */;
Psalm output (using commit 10ea05a):

INFO: Trace - 28:38 - $_merged_iterable: SplFixedArray<mixed>

@AndrolGenhald
Copy link
Collaborator

FYI line 23 is also a false negative that will be fixed by #8044, unpacking an iterable with non-array-key keys is a fatal error.

@orklah
Copy link
Collaborator

orklah commented Jul 29, 2022

output changed radically, did the situation improve?

@AndrolGenhald
Copy link
Collaborator

@orklah nope, just the false negative I mentioned showing up everywhere. Here's a fixed version of the second link: https://psalm.dev/r/0d58749a8f

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/0d58749a8f
<?php

declare(strict_types=1);

/**
 * @return SplFixedArray<int>
 */
function getTraversable(): SplFixedArray
{
    return SplFixedArray::fromArray([1, 2, 3]);
}

/**
 * @template A
 * @template B
 *
 * @param iterable<int, A> $lhs
 * @param iterable<int, B> $rhs
 * @return SplFixedArray<A|B>
 */
function mergeIterable(iterable $lhs, iterable $rhs): SplFixedArray
{
    return SplFixedArray::fromArray([...$lhs, ...$rhs]); 
}

// Expected SplFixedArray<int>, actual SplFixedArray<mixed>
$_merged_iterable = mergeIterable(getTraversable(), getTraversable());
/** @psalm-trace $_merged_iterable */;
Psalm output (using commit 7c4228f):

INFO: Trace - 28:38 - $_merged_iterable: SplFixedArray<mixed>

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.

3 participants