phpstan icon indicating copy to clipboard operation
phpstan copied to clipboard

Excluding all enum cases one by one does not simplify a return type when using `getAllowedSubTypes` involving an enum

Open stof opened this issue 2 years ago • 6 comments
trafficstars

Bug report

When an extension implements getAllowedSubTypes to define that the only allowed subtypes of an interface are a given class and an enum, I would except that handling each case of the enum would leave us with a type refined to the other class, just like it does for union types.

Code snippet that reproduces the problem

https://phpstan.org/r/deeced13-4be2-4ce2-86d8-ee547748f18a

Expected output

When running that with the jiripudil/phpstan-sealed-classes extension installed, I would expect no error. This extension defines an AllowedSubTypesClassReflectionExtension reading the Sealed attribute to provide the allowed subtypes.

Replacing the sealed interface (for which the extension defines the 2 allowed subtypes) with a union type of the 2 allowed subtypes does not report the error: https://phpstan.org/r/0c528e9b-ab4d-4811-ba45-dbe16b42ffac

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

No response

stof avatar Nov 17 '23 18:11 stof

Hi, could you please prove the point of this bug without any extension involved on phpstan.org/try? For example with \PHPStan\dumpType calls.

ondrejmirtes avatar Nov 25 '23 10:11 ondrejmirtes

Oh I get it. We need to update ObjectType::getEnumCases() so that it reads ClassReflection::getAllowedSubTypes().

ondrejmirtes avatar Nov 29 '23 08:11 ondrejmirtes

I don't see how to reproduce it on the payground as it involves ClassReflection::getAllowedSubTypes()

stof avatar Nov 29 '23 08:11 stof

Yeah sure, I realized you can't.

ondrejmirtes avatar Nov 29 '23 08:11 ondrejmirtes

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

@@ @@
-PHP 8.1 – 8.3 (3 errors)
+PHP 8.1 – 8.3 (6 errors)
 ==========
 
  5: Attribute class JiriPudil\SealedClasses\Sealed does not exist.
 48: Call to an undefined method ColorFormat::getOriginal().
 61: Call to an undefined method ColorFormat::getOriginal().
+65: Function writeRgb() returns void but does not have any side effects.
+68: Function writeHsl() returns void but does not have any side effects.
+72: Function write() returns void but does not have any side effects.
 
 PHP 7.2 – 8.0 (1 error)
 ==========
 
 11: Syntax error, unexpected T_STRING on line 11
Full report

PHP 8.1 – 8.3 (6 errors)

Line Error
5 Attribute class JiriPudil\SealedClasses\Sealed does not exist.
48 Call to an undefined method ColorFormat::getOriginal().
61 Call to an undefined method ColorFormat::getOriginal().
65 Function writeRgb() returns void but does not have any side effects.
68 Function writeHsl() returns void but does not have any side effects.
72 Function write() returns void but does not have any side effects.

PHP 7.2 – 8.0 (1 error)

Line Error
11 Syntax error, unexpected T_STRING on line 11

phpstan-bot avatar Mar 29 '24 10:03 phpstan-bot

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

@@ @@
-PHP 8.1 – 8.3
+PHP 8.1 – 8.3 (3 errors)
 ==========
 
-No errors
+62: Function writeRgb() returns void but does not have any side effects.
+65: Function writeHsl() returns void but does not have any side effects.
+69: Function write() returns void but does not have any side effects.
 
 PHP 7.2 – 8.0 (1 error)
 ==========
 
  8: Syntax error, unexpected T_STRING on line 8
Full report

PHP 8.1 – 8.3 (3 errors)

Line Error
62 Function writeRgb() returns void but does not have any side effects.
65 Function writeHsl() returns void but does not have any side effects.
69 Function write() returns void but does not have any side effects.

PHP 7.2 – 8.0 (1 error)

Line Error
8 Syntax error, unexpected T_STRING on line 8

phpstan-bot avatar Mar 29 '24 10:03 phpstan-bot

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

@@ @@
 48: Call to an undefined method ColorFormat::getOriginal().
 61: Call to an undefined method ColorFormat::getOriginal().
 
-PHP 7.2 – 8.0 (1 error)
+PHP 8.0 (2 errors)
+==========
+
+11: Syntax error, unexpected T_STRING on line 11
+25: Syntax error, unexpected T_STRING, expecting T_VARIABLE on line 25
+
+PHP 7.2 – 7.4 (1 error)
 ==========
 
 11: Syntax error, unexpected T_STRING on line 11
Full report

PHP 8.1 – 8.3 (3 errors)

Line Error
5 Attribute class JiriPudil\SealedClasses\Sealed does not exist.
48 Call to an undefined method ColorFormat::getOriginal().
61 Call to an undefined method ColorFormat::getOriginal().

PHP 8.0 (2 errors)

Line Error
11 Syntax error, unexpected T_STRING on line 11
25 Syntax error, unexpected T_STRING, expecting T_VARIABLE on line 25

PHP 7.2 – 7.4 (1 error)

Line Error
11 Syntax error, unexpected T_STRING on line 11

phpstan-bot avatar Sep 15 '24 18:09 phpstan-bot

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

@@ @@
 
 No errors
 
-PHP 7.2 – 8.0 (1 error)
+PHP 8.0 (2 errors)
+==========
+
+ 8: Syntax error, unexpected T_STRING on line 8
+22: Syntax error, unexpected T_STRING, expecting T_VARIABLE on line 22
+
+PHP 7.2 – 7.4 (1 error)
 ==========
 
  8: Syntax error, unexpected T_STRING on line 8
Full report

PHP 8.1 – 8.3

No errors

PHP 8.0 (2 errors)

Line Error
8 Syntax error, unexpected T_STRING on line 8
22 Syntax error, unexpected T_STRING, expecting T_VARIABLE on line 22

PHP 7.2 – 7.4 (1 error)

Line Error
8 Syntax error, unexpected T_STRING on line 8

phpstan-bot avatar Sep 15 '24 18:09 phpstan-bot