Skip to content

static(Class<NarrowedTemplateValue>) does not apply the NarrowedTemplateValue in conditional on instance var #13779

@EmielM

Description

@EmielM

Bug report

See playground, where I'm trying to typecheck our little ORM abstraction to see if records are backed, meaning we know the ->id is int when IsBackedT is true.

Code snippet that reproduces the problem

https://phpstan.org/r/bfaf491b-c44f-47ce-b6c5-e34c42f7b124

Expected output

A few issues I'm struggling to understand. Could be me, or otherwise some bugs or (ideas for) possible improvements:

  • Method DBRecord::newInstance() should return static(DBRecord<IsBackedT of bool>) but returns static(DBRecord<bool>); are these different types?
  • It looks like @phpstan-self-out static<true> does narrow the type to static(DBRecord<true>), but then accessing ->id does not use the conditional. Probably because of the static(...) thing, but I don't want to narrow to self<true>. I also tried @phpstan-self-out (static & DBRecord<true>) (which I thought would be the same as static(DBRecord<true>)), no luck
  • For assertBacked, using phpstan-self-out is a weird hack, would be better to somehow support the generic narrowing through @phpstan-assert, couldn't get that to work
  • It is weird that there is no construct to disallow functions conditionally based on a template type. If it would accept parameters, you could condition those to never. For this case I have @return MyCondition ? void : never, but violations are catched on the next line only. Analog to @phpstan-self-out, perhaps a @phpstan-self-in could be an idea?

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

We have twice the amount of holidays now that we use PHPstan, because things stopped breaking

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions