Skip to content

Supporting sealed class hierarchies in match #12241

@danrot

Description

@danrot

Feature request

I have already seen #9010, and I'll paste the playground from that issue here as a reference: https://phpstan.org/r/8df4601c-f29b-4187-b58c-8f7480a54e57

In the other issue you've correctly mentioned that this cannot fully work, because there is always the chance that somebody will introduce another sub class somewhere. This is totally true for libraries, but in applications/projects it is probably very hypothetical.

I am mostly working on projects, whose source code is not even publicly available. So the only possibility that there will be another sub class of an abstract class I've defined in my own application, is that I add such a subclass within the same application on my own. Given that, I think it would make sense to somehow opt-in to the behavior that was suggested in #9010. I could imagine that being a PHPDoc annotation or something like that, just a quick sketch:

<?php declare(strict_types = 1);

/**
 * @phpstan-sealed-subclasses
 */
abstract class Foo{}

class Bar extends Foo{}
class Baz extends Foo{}

function (Foo $foo): string {
    return match ($foo::class) {
      Bar::class => 'Bar',
      Baz::class => 'Baz',
	};
};

By adding this @phpstan-sealed-subclasses (not sure about that name though), I am kind of saying that all sub classes of this abstract class are known at static analysis time, and there is no way somebody else can add that something else to that class hierarchy other than adding it to the application/project code itself.

The thing is that the only workaround I found for this so far is to use Bar|Baz everywhere instead of just Foo, which is especially cumbersome if you have many sub classes...

What do you think about this proposal?

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

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions