Visitar URL original
2.3.0: property.promotedNotSupported in a PHP_VERSION_ID-guarded branch when phpVersion is fixed · Issue #15425 · phpstan/phpstan · GitHub
Skip to content

2.3.0: property.promotedNotSupported in a PHP_VERSION_ID-guarded branch when phpVersion is fixed #15425

Description

@lstrojny

Bug report

With a fixed phpVersion, a branch guarded by PHP_VERSION_ID that can't run on that version isn't treated as dead. Instead, PHP_VERSION_ID widens to the lowest version PHPStan knows. On 2.3.0, InvalidPromotedPropertiesRule reads that scope version, so a polyfill class with promoted properties in such a branch now fails with a non-ignorable error:

Promoted properties are supported only on PHP 8.0 and later.
🪪 property.promotedNotSupported (non-ignorable)

The widening itself is older; 2.2.16 and 2.2.17 dump the same type. 2.3.0 is the first release where it produces an error.

We hit it on a Deprecated attribute polyfill guarded with if (PHP_VERSION_ID < 80400 && !class_exists(Deprecated::class)). Our dev config pins phpVersion: 80500 to lint against the latest PHP. Our CI config uses the composer php: >=8.1 range and isn't affected.

Code snippet that reproduces the problem

phpstan.neon:

parameters:
    level: 0
    phpVersion: 80500

bug.php:

<?php declare(strict_types = 1);

if (PHP_VERSION_ID < 80400) {
	\PHPStan\dumpType(PHP_VERSION_ID);

	final class Foo
	{
		public function __construct(public ?string $message = null)
		{
		}
	}
}

On the playground, select PHP 8.5.

Output on 2.3.0:

  4      Dumped type: int<50207, 80399>
  8      Promoted properties are supported only on PHP 8.0 and later.

Output on 2.2.16 and 2.2.17:

  4      Dumped type: int<50207, 80399>

Expected output

No property.promotedNotSupported error. The branch can't run on PHP 8.5, so I'd expect either the branch to count as unreachable, or PHP_VERSION_ID to keep the configured lower bound of 80500. Either way, the narrowed version shouldn't drop below what phpVersion allows.

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

It found an unused parameter and a dead return value in our test fixtures in the same upgrade. Thanks!

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions