+
Skip to content

Conversation

maks-rafalko
Copy link
Member

@maks-rafalko maks-rafalko commented Jun 7, 2025

I've analyzed 200+ mutations in BetterReflection (Roave/BetterReflection#1510) and there are many cases where PHPStan kills a mutant while it should not - those are false-positives (meaning we get killed mutant but in fact it can be escaped/not well testes), for example:

@@ @@
             if ($reflection instanceof ReflectionFunction && $this->containsLine($reflection, $lineNumber)) {
                 return $reflection;
             }
-            if ($reflection instanceof ReflectionConstant && $this->containsLine($reflection, $lineNumber)) {
+            if (true && $this->containsLine($reflection, $lineNumber)) {
                 return $reflection;
             }
         }

$ '/app/vendor/bin/phpstan' '--tmp-file=/tmp/infection/mutant.a99f5bbe9bbbb1514da2bdbe5e315d5c.infection.php' '--instead-of=/app/src/Util/FindReflectionOnLine.php' '--error-format=json' '--no-progress' '-vv'

PHPStan error: Left side of && is always true.

In PHPStan, it always produces "Left|Right side of && is always true" or "If condition is always true."

See https://phpstan.org/r/a9736cca-dc3a-4033-8f2a-80dbc13951b9

So it doesn't make sense for InstanceOf_ mutator to try to kill it by PHPStan, because it will always be killed while tests can be with the whole.

I've analuzed 200+ mutations in BetterReflection (Roave/BetterReflection#1510) and there are many cases where PHPStan kills a mutant while it should not - those are false-positives (meaning we get killed mutant but in fact it can be escaped/not well testes), for example:

```diff
@@ @@
             if ($reflection instanceof ReflectionFunction && $this->containsLine($reflection, $lineNumber)) {
                 return $reflection;
             }
-            if ($reflection instanceof ReflectionConstant && $this->containsLine($reflection, $lineNumber)) {
+            if (true && $this->containsLine($reflection, $lineNumber)) {
                 return $reflection;
             }
         }

$ '/app/vendor/bin/phpstan' '--tmp-file=/tmp/infection/mutant.a99f5bbe9bbbb1514da2bdbe5e315d5c.infection.php' '--instead-of=/app/src/Util/FindReflectionOnLine.php' '--error-format=json' '--no-progress' '-vv'

PHPStan error: Left side of && is always true.
```

In PHPStan, it always produces "Left|Right side of && is always true" or "If condition is always true."

See https://phpstan.org/r/a9736cca-dc3a-4033-8f2a-80dbc13951b9

So it doesn't make sense for `InstanceOf_` mutator to try to kill it by PHPStan, because it will always be killed while tests can be with the whole.
@staabm
Copy link
Contributor

staabm commented Jun 7, 2025

So it doesn't make sense for InstanceOf_ mutator to try to kill it by PHPStan, because it will always be killed while tests can be with the whole.

sounds like it might make sense to ignore some errors via phpstan-identifier via phpstan config.
(or for certain errors there might also be a feature flag to disable them).

maybe we even need such a "phpstan-ignore-list" per mutator, to make sure PHPStan does not kill errors by mistake.
I think we also need to check whether we should run only phpstan-core e.g. by disabling PHPStan extension installer.
running only phpstan-core might also help to find the correct identifiers to ignore (as the list of rules gest shorter).. otherwise this list might be endless and even 3rd party rules might report something which is not useful, but we didn't forsee.

@maks-rafalko
Copy link
Member Author

maks-rafalko commented Jun 7, 2025

sounds like it might make sense to ignore some errors via phpstan-identifier via phpstan config.

idea here was not to run PHPStan at all (in this particular case), because running it even for 1-file project takes at least 1 second (it's super slow comparing to PHPUnit).

I don't say that it excludes your idea, just saying that instead of running PHPStan and disabling this check we can not run it. But this needs to be tested.

Can we only ignore PHPStan identifiers by adding them to temp config file or do you know how to do it by CLI? I didn't find any CLI option for this.

I think we also need to check whether we should run only phpstan-core

Interesting, will keep an eye on it, analyzing results.

@maks-rafalko
Copy link
Member Author

I will experiment with your idea and keep this PR on hold

@staabm
Copy link
Contributor

staabm commented Jun 8, 2025

In PHPStan, it always produces "Left|Right side of && is always true" or "If condition is always true."

I wonder whether we would get better results when then mutator would produce !($a instanceof A) instead of just plain true or false which is not meaningful for PHPStan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载