Skip to content

Type mismatch when explicitly setting an array key #11507

Open

Description

@liamduckett

Bug report

Hey, apologies I'm not exactly sure exactly how to explain / label this - hoping the playground link will explain itself...

Function foo() should return Collection<int, non-empty-array<string, string>> but returns Collection<int, non-empty-array<string, string>>.

Is a strange error itself (as the two signatures match). The error provides a tip:

Template type TValue on class Collection is not covariant. Learn more: What's Up With @template-covariant?
return.type

Which I am at least familiar with (although I have to admit it is a topic I revisit often...)

I don't (possibly naively) see how it could be relevant though, as non-empty-array<string, string> should be compatible with itself, even when checking for invariance (right?).

I'm also not convinced I've found the simplest example (do I even need the collection and map? could I recreate this with a simple array?), however it is as much progress I have made tonight. Will likely update later this week.

Code snippet that reproduces the problem

https://phpstan.org/r/9201882a-6812-4d14-a2e4-ccdec7d46446

Expected output

I'd expect this to report no error

Did PHPStan help you today? Did it make you happy in any way?

Absolutely! The time I've spent debugging my code, and simplying it to create this example has been great fun. I'd love to get into contributing to PHPStan 🙂

Activity

  1. added this to the Generics milestone on Aug 14, 2024
  2. liamduckett commented on Aug 15, 2024

    @liamduckett
    Author
  3. phpstan-bot commented on Sep 16, 2024

    @phpstan-bot
    Contributor

    @liamduckett After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:

    @@ @@
    -PHP 8.0 – 8.3 (1 error)
    +PHP 8.0 – 8.3 (2 errors)
     ==========
     
    +31: Parameter #1 $items of class Collection constructor expects list<TMapValue>, array<int<0, max>, TMapValue> given.
     41: Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.
     
     PHP 7.2 – 7.4 (3 errors)
    @@ @@
     ==========
     
     11: Promoted properties are supported only on PHP 8.0 and later.
    -31: Parameter #1 $items of class Collection constructor expects array<int, TMapValue>, array<int, TMapValue>|false given.
    +31: Parameter #1 $items of class Collection constructor expects list<TMapValue>, array<int<0, max>, TMapValue>|false given.
     41: Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.
    Full report

    PHP 8.0 – 8.3 (2 errors)

    Line Error
    31 Parameter #1 $items of class Collection constructor expects list<TMapValue>, array<int<0, max>, TMapValue> given.
    41 Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.

    PHP 7.2 – 7.4 (3 errors)

    Line Error
    11 Promoted properties are supported only on PHP 8.0 and later.
    31 `Parameter #1 $items of class Collection constructor expects list, array<int<0, max>, TMapValue>
    41 Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.
  4. ondrejmirtes commented on Dec 10, 2024

    @ondrejmirtes
    Member

    Deleted the phpstan-bot comments, they weren't correct.

  5. deleted a comment from phpstan-bot on Dec 10, 2024
  6. deleted a comment from phpstan-bot on Dec 10, 2024
  7. phpstan-bot commented on Feb 1, 2025

    @phpstan-bot
    Contributor

    @liamduckett After the latest push in 2.1.x, PHPStan now reports different result with your code snippet:

    @@ @@
    -PHP 8.0 – 8.3 (1 error)
    +PHP 8.0 – 8.3 (2 errors)
     ==========
     
    +33: Method Collection::map() should return static(Collection<TKey of (int|string), TMapValue>) but returns Collection<TKey of (int|string), TMapValue>.
     43: Function foo() should return Collection<int, non-empty-array<string, string>> but returns Collection<int, non-empty-array<string, string>>.
     
    -PHP 7.2 – 7.4 (3 errors)
    +PHP 7.2 – 7.4 (4 errors)
     ==========
     
     13: Promoted properties are supported only on PHP 8.0 and later.
    +33: Method Collection::map() should return static(Collection<TKey of (int|string), TMapValue>) but returns Collection<TKey of (int|string), TMapValue>.
     33: Parameter #1 $items of class Collection constructor expects array<TKey of (int|string), TMapValue>, array<TKey of (int|string), TMapValue>|false given.
     43: Function foo() should return Collection<int, non-empty-array<string, string>> but returns Collection<int, non-empty-array<string, string>>.
    Full report

    PHP 8.0 – 8.3 (2 errors)

    Line Error
    33 `Method Collection::map() should return static(Collection<TKey of (int
    43 Function foo() should return Collection<int, non-empty-array<string, string>> but returns Collection<int, non-empty-array<string, string>>.

    PHP 7.2 – 7.4 (4 errors)

    Line Error
    13 Promoted properties are supported only on PHP 8.0 and later.
    33 `Method Collection::map() should return static(Collection<TKey of (int
    33 `Parameter #1 $items of class Collection constructor expects array<TKey of (int
    43 Function foo() should return Collection<int, non-empty-array<string, string>> but returns Collection<int, non-empty-array<string, string>>.
  8. phpstan-bot commented on Feb 1, 2025

    @phpstan-bot
    Contributor

    @liamduckett After the latest push in 2.1.x, PHPStan now reports different result with your code snippet:

    @@ @@
    -PHP 8.0 – 8.3 (1 error)
    +PHP 8.0 – 8.3 (3 errors)
     ==========
     
    +31: Method Collection::map() should return static(Collection<TMapValue>) but returns Collection<TMapValue>.
    +31: Parameter #1 $items of class Collection constructor expects list<TMapValue>, array<int<0, max>, TMapValue> given.
     41: Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.
     
    -PHP 7.2 – 7.4 (3 errors)
    +PHP 7.2 – 7.4 (4 errors)
     ==========
     
     11: Promoted properties are supported only on PHP 8.0 and later.
    -31: Parameter #1 $items of class Collection constructor expects array<int, TMapValue>, array<int, TMapValue>|false given.
    +31: Method Collection::map() should return static(Collection<TMapValue>) but returns Collection<TMapValue>.
    +31: Parameter #1 $items of class Collection constructor expects list<TMapValue>, array<int<0, max>, TMapValue>|false given.
     41: Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.
    Full report

    PHP 8.0 – 8.3 (3 errors)

    Line Error
    31 Method Collection::map() should return static(Collection<TMapValue>) but returns Collection<TMapValue>.
    31 Parameter #1 $items of class Collection constructor expects list<TMapValue>, array<int<0, max>, TMapValue> given.
    41 Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.

    PHP 7.2 – 7.4 (4 errors)

    Line Error
    11 Promoted properties are supported only on PHP 8.0 and later.
    31 Method Collection::map() should return static(Collection<TMapValue>) but returns Collection<TMapValue>.
    31 `Parameter #1 $items of class Collection constructor expects list, array<int<0, max>, TMapValue>
    41 Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.
  9. liamduckett commented on Feb 1, 2025

    @liamduckett
    Author

    Example that reproduces issue, without other (new) issues:

    https://phpstan.org/r/576494fb-e4bc-4920-9b6d-5ee68ab4c167

  10. added a commit that references this issue on Mar 29, 2026
    7b29df6
  11. phpstan-bot commented on Sep 7, 2026

    @phpstan-bot
    Contributor

    @liamduckett After the latest push in 2.3.x, PHPStan now reports different result with your code snippet:

    @@ @@
    -PHP 8.0 – 8.4 (1 error)
    +PHP 8.0 – 8.4
     ==========
     
    -43: Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.
    +No errors
     
    -PHP 7.2 – 7.4 (3 errors)
    +PHP 7.2 – 7.4 (2 errors)
     ==========
     
     13: Promoted properties are supported only on PHP 8.0 and later.
    -33: Parameter #1 $items of class Collection constructor expects array<int, TMapValue>, array<int, TMapValue>|false given.
    -43: Function foo() should return Collection<non-empty-array<string>> but returns Collection<non-empty-array<string>>.
    +33: Parameter #1 $items of class Collection constructor expects array<int, TMapValue>, array<int, TMapValue>|false given.
    Full report

    PHP 8.0 – 8.4

    No errors

    PHP 7.2 – 7.4 (2 errors)

    Line Error
    13 Promoted properties are supported only on PHP 8.0 and later.
    33 `Parameter #1 $items of class Collection constructor expects array<int, TMapValue>, array<int, TMapValue>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions