Skip to content

Accessing ::class or calling get_class() on nullable types does not lead to a warning #13069

Open
phpstan/phpstan-src
#4011
@driehle

Description

@driehle

Bug report

I noticed that the following code produces four warnings:

<?php

use function PHPStan\Testing\assertType;

interface ResourceInterface {}

class Person implements ResourceInterface 
{
	public function getName(): string { return 'Name'; }
}

class Account implements ResourceInterface
{
	public function getMail(): string  { return 'Mail'; }
}

function foo(?ResourceInterface $object = null): void
{
	switch ($object::class) {
		case Person::class:
			assertType(Person::class, $object);
			echo $object->getName();
			break;
		case Account::class:
			assertType(Account::class, $object);
			echo $object->getMail();
			break;
	}
}
Line Error Type
21 Expected type Person, actual: ResourceInterface|null Non-ignorable
22 Call to an undefined method ResourceInterface::getName(). method.notFound
25 Expected type Account, actual: ResourceInterface|null Non-ignorable
26 Call to an undefined method ResourceInterface::getMail(). method.notFound

Code snippet that reproduces the problem

https://phpstan.org/r/f9c2c069-07b2-46a3-b83c-837205e6581f

Expected output

The errors surprised me, as the type is actually checked and, hence, the code reported by PhpStan will not produce any errors during runtime. The feature of checking types by switch was covered in #745, #4896.

I found, however, that the code above seems to be related to $object being nullable. If you change the method signature from ?ResourceInterface $object = null to ResourceInterface $object, the errors are suddenly gone!

Next, I discovered that accessing ::class on null actually throws an error in PHP 8.4.7 (and probably all PHP 8 versions):

$ php -r "\$foo = null; var_dump(\$foo::class);"
PHP Fatal error:  Uncaught TypeError: Cannot use "::class" on null in Command line code:1
Stack trace:
#0 {main}
  thrown in Command line code on line 1

So PhpStan is actually right in reporting something, though I think the reported errors are incorect. In my opinion, PhpStan should complain about accessing ::class on nullable types.

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

No response

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