Skip to content

Commit d00b769

Browse files
committed
Rules about #[NoDiscard] report errors only on PHP 8.5+, errors are non-ignorable
Use the `(void)` cast to ignore them.
1 parent 53b87e0 commit d00b769

7 files changed

+47
-9
lines changed

src/Php/PhpVersion.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,4 +434,9 @@ public function supportsVoidCast(): bool
434434
return $this->versionId >= 80500;
435435
}
436436

437+
public function supportsNoDiscardAttribute(): bool
438+
{
439+
return $this->versionId >= 80500;
440+
}
441+
437442
}

src/Rules/Functions/CallToFunctionStatementWithNoDiscardRule.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\DependencyInjection\RegisteredRule;
8+
use PHPStan\Php\PhpVersion;
89
use PHPStan\Reflection\ReflectionProvider;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Rules\RuleErrorBuilder;
@@ -19,7 +20,10 @@
1920
final class CallToFunctionStatementWithNoDiscardRule implements Rule
2021
{
2122

22-
public function __construct(private ReflectionProvider $reflectionProvider)
23+
public function __construct(
24+
private ReflectionProvider $reflectionProvider,
25+
private PhpVersion $phpVersion,
26+
)
2327
{
2428
}
2529

@@ -38,6 +42,10 @@ public function processNode(Node $node, Scope $scope): array
3842
return [];
3943
}
4044

45+
if (!$this->phpVersion->supportsNoDiscardAttribute()) {
46+
return [];
47+
}
48+
4149
$funcCall = $node->expr;
4250
if ($funcCall->name instanceof Node\Name) {
4351
if (!$this->reflectionProvider->hasFunction($funcCall->name, $scope)) {
@@ -53,7 +61,7 @@ public function processNode(Node $node, Scope $scope): array
5361
RuleErrorBuilder::message(sprintf(
5462
'Call to function %s() on a separate line discards return value.',
5563
$function->getName(),
56-
))->identifier('function.resultDiscarded')->build(),
64+
))->identifier('function.resultDiscarded')->nonIgnorable()->build(),
5765
];
5866
}
5967

@@ -75,7 +83,7 @@ public function processNode(Node $node, Scope $scope): array
7583
RuleErrorBuilder::message(sprintf(
7684
'Call to callable %s on a separate line discards return value.',
7785
$callableType->describe(VerbosityLevel::value()),
78-
))->identifier('callable.resultDiscarded')->build(),
86+
))->identifier('callable.resultDiscarded')->nonIgnorable()->build(),
7987
];
8088
}
8189

src/Rules/Methods/CallToMethodStatementWithNoDiscardRule.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Analyser\NullsafeOperatorHelper;
77
use PHPStan\Analyser\Scope;
88
use PHPStan\DependencyInjection\RegisteredRule;
9+
use PHPStan\Php\PhpVersion;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Rules\RuleErrorBuilder;
1112
use PHPStan\Rules\RuleLevelHelper;
@@ -20,7 +21,10 @@
2021
final class CallToMethodStatementWithNoDiscardRule implements Rule
2122
{
2223

23-
public function __construct(private RuleLevelHelper $ruleLevelHelper)
24+
public function __construct(
25+
private RuleLevelHelper $ruleLevelHelper,
26+
private PhpVersion $phpVersion,
27+
)
2428
{
2529
}
2630

@@ -41,6 +45,10 @@ public function processNode(Node $node, Scope $scope): array
4145
return [];
4246
}
4347

48+
if (!$this->phpVersion->supportsNoDiscardAttribute()) {
49+
return [];
50+
}
51+
4452
$funcCall = $node->expr;
4553
if (!$funcCall->name instanceof Node\Identifier) {
4654
return [];
@@ -77,7 +85,7 @@ public function processNode(Node $node, Scope $scope): array
7785
$method->isStatic() ? 'static method' : 'method',
7886
$method->getDeclaringClass()->getDisplayName(),
7987
$method->getName(),
80-
))->identifier('method.resultDiscarded')->build(),
88+
))->identifier('method.resultDiscarded')->nonIgnorable()->build(),
8189
];
8290
}
8391

src/Rules/Methods/CallToStaticMethodStatementWithNoDiscardRule.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Analyser\NullsafeOperatorHelper;
77
use PHPStan\Analyser\Scope;
88
use PHPStan\DependencyInjection\RegisteredRule;
9+
use PHPStan\Php\PhpVersion;
910
use PHPStan\Reflection\ReflectionProvider;
1011
use PHPStan\Rules\Rule;
1112
use PHPStan\Rules\RuleErrorBuilder;
@@ -25,6 +26,7 @@ final class CallToStaticMethodStatementWithNoDiscardRule implements Rule
2526
public function __construct(
2627
private RuleLevelHelper $ruleLevelHelper,
2728
private ReflectionProvider $reflectionProvider,
29+
private PhpVersion $phpVersion,
2830
)
2931
{
3032
}
@@ -44,6 +46,10 @@ public function processNode(Node $node, Scope $scope): array
4446
return [];
4547
}
4648

49+
if (!$this->phpVersion->supportsNoDiscardAttribute()) {
50+
return [];
51+
}
52+
4753
$funcCall = $node->expr;
4854
if (!$funcCall->name instanceof Node\Identifier) {
4955
return [];
@@ -90,7 +96,7 @@ public function processNode(Node $node, Scope $scope): array
9096
$method->isStatic() ? 'static method' : 'method',
9197
$method->getDeclaringClass()->getDisplayName(),
9298
$method->getName(),
93-
))->identifier('staticMethod.resultDiscarded')->build(),
99+
))->identifier('staticMethod.resultDiscarded')->nonIgnorable()->build(),
94100
];
95101
}
96102

tests/PHPStan/Rules/Functions/CallToFunctionStatementWithNoDiscardRuleTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
namespace PHPStan\Rules\Functions;
44

5+
use PHPStan\Php\PhpVersion;
56
use PHPStan\Rules\Rule;
67
use PHPStan\Testing\RuleTestCase;
78
use PHPUnit\Framework\Attributes\RequiresPhp;
9+
use const PHP_VERSION_ID;
810

911
/**
1012
* @extends RuleTestCase<CallToFunctionStatementWithNoDiscardRule>
@@ -14,10 +16,10 @@ class CallToFunctionStatementWithNoDiscardRuleTest extends RuleTestCase
1416

1517
protected function getRule(): Rule
1618
{
17-
return new CallToFunctionStatementWithNoDiscardRule(self::createReflectionProvider());
19+
return new CallToFunctionStatementWithNoDiscardRule(self::createReflectionProvider(), new PhpVersion(PHP_VERSION_ID));
1820
}
1921

20-
#[RequiresPhp('>= 8.1')]
22+
#[RequiresPhp('>= 8.5')]
2123
public function testRule(): void
2224
{
2325
$this->analyse([__DIR__ . '/data/function-call-statement-result-discarded.php'], [

tests/PHPStan/Rules/Methods/CallToMethodStatementWithNoDiscardRuleTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
namespace PHPStan\Rules\Methods;
44

5+
use PHPStan\Php\PhpVersion;
56
use PHPStan\Rules\Rule;
67
use PHPStan\Rules\RuleLevelHelper;
78
use PHPStan\Testing\RuleTestCase;
9+
use PHPUnit\Framework\Attributes\RequiresPhp;
10+
use const PHP_VERSION_ID;
811

912
/**
1013
* @extends RuleTestCase<CallToMethodStatementWithNoDiscardRule>
@@ -14,9 +17,10 @@ class CallToMethodStatementWithNoDiscardRuleTest extends RuleTestCase
1417

1518
protected function getRule(): Rule
1619
{
17-
return new CallToMethodStatementWithNoDiscardRule(new RuleLevelHelper(self::createReflectionProvider(), true, false, true, false, false, false, true));
20+
return new CallToMethodStatementWithNoDiscardRule(new RuleLevelHelper(self::createReflectionProvider(), true, false, true, false, false, false, true), new PhpVersion(PHP_VERSION_ID));
1821
}
1922

23+
#[RequiresPhp('>= 8.5')]
2024
public function testRule(): void
2125
{
2226
$this->analyse([__DIR__ . '/data/method-call-statement-result-discarded.php'], [

tests/PHPStan/Rules/Methods/CallToStaticMethodStatementWithNoDiscardRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
namespace PHPStan\Rules\Methods;
44

5+
use PHPStan\Php\PhpVersion;
56
use PHPStan\Rules\Rule;
67
use PHPStan\Rules\RuleLevelHelper;
78
use PHPStan\Testing\RuleTestCase;
9+
use PHPUnit\Framework\Attributes\RequiresPhp;
10+
use const PHP_VERSION_ID;
811

912
/**
1013
* @extends RuleTestCase<CallToStaticMethodStatementWithNoDiscardRule>
@@ -18,9 +21,11 @@ protected function getRule(): Rule
1821
return new CallToStaticMethodStatementWithNoDiscardRule(
1922
new RuleLevelHelper($reflectionProvider, true, false, true, false, false, false, true),
2023
$reflectionProvider,
24+
new PhpVersion(PHP_VERSION_ID),
2125
);
2226
}
2327

28+
#[RequiresPhp('>= 8.5')]
2429
public function testRule(): void
2530
{
2631
$this->analyse([__DIR__ . '/data/static-method-call-statement-result-discarded.php'], [

0 commit comments

Comments
 (0)