Skip to content

Commit 0f06587

Browse files
ondrejmirtesclaude
andcommitted
Run the NoDiscard rule tests wherever their syntax parses
76f47dd dropped the PHP 8.5 requirement from the three NoDiscard rule tests, but their fixtures still use the pipe operator and the (void) cast, which are PHP 8.5 syntax - on the PHP 7.4 job the pipe token cannot even be lexed. Each fixture is split: the plain calls stay in the original file and run on every PHP with attributes (7.4 reads #[\NoDiscard] as a comment, so nothing would be reported there), the (void) casts and pipes move to a -php85 fixture behind #[RequiresPhp('>= 8.5.0')]. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DfQHLTyyoMfjfa4sXJCGa5
1 parent 77badfd commit 0f06587

9 files changed

Lines changed: 174 additions & 82 deletions

‎tests/PHPStan/Rules/Functions/CallToFunctionStatementWithNoDiscardRuleTest.php‎

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\Rules\Rule;
66
use PHPStan\Testing\RuleTestCase;
7+
use PHPUnit\Framework\Attributes\RequiresPhp;
78

89
/**
910
* @extends RuleTestCase<CallToFunctionStatementWithNoDiscardRule>
@@ -16,6 +17,8 @@ protected function getRule(): Rule
1617
return new CallToFunctionStatementWithNoDiscardRule(self::createReflectionProvider());
1718
}
1819

20+
// #[\NoDiscard] is an attribute, a comment on PHP 7.4
21+
#[RequiresPhp('>= 8.0.0')]
1922
public function testRule(): void
2023
{
2124
$this->analyse([__DIR__ . '/data/function-call-statement-result-discarded.php'], [
@@ -25,47 +28,55 @@ public function testRule(): void
2528
],
2629
[
2730
'Call to function FunctionCallStatementResultDiscarded\differentCase() on a separate line discards return value.',
28-
25,
31+
23,
2932
],
3033
[
3134
'Call to callable \'FunctionCallStateme…\' on a separate line discards return value.',
32-
30,
35+
28,
3336
],
3437
[
3538
'Call to callable Closure(int): array on a separate line discards return value.',
36-
35,
39+
33,
3740
],
3841
[
3942
'Call to callable Closure(): 1 on a separate line discards return value.',
40-
40,
43+
38,
4144
],
4245
[
4346
'Call to callable Closure(): 1 on a separate line discards return value.',
44-
45,
47+
43,
4548
],
49+
]);
50+
}
51+
52+
// the (void) cast and the pipe operator are PHP 8.5 syntax
53+
#[RequiresPhp('>= 8.5.0')]
54+
public function testRulePhp85(): void
55+
{
56+
$this->analyse([__DIR__ . '/data/function-call-statement-result-discarded-php85.php'], [
4657
[
47-
'Call to function FunctionCallStatementResultDiscarded\canDiscard() in (void) cast but function allows discarding return value.',
48-
55,
58+
'Call to function FunctionCallStatementResultDiscardedPhp85\canDiscard() in (void) cast but function allows discarding return value.',
59+
17,
4960
],
5061
[
5162
'Call to callable \'FunctionCallStateme…\' in (void) cast but callable allows discarding return value.',
52-
59,
63+
20,
5364
],
5465
[
55-
'Call to function FunctionCallStatementResultDiscarded\withSideEffects() on a separate line discards return value.',
56-
61,
66+
'Call to function FunctionCallStatementResultDiscardedPhp85\withSideEffects() on a separate line discards return value.',
67+
22,
5768
],
5869
[
59-
'Call to function FunctionCallStatementResultDiscarded\canDiscard() in (void) cast but function allows discarding return value.',
60-
64,
70+
'Call to function FunctionCallStatementResultDiscardedPhp85\canDiscard() in (void) cast but function allows discarding return value.',
71+
25,
6172
],
6273
[
63-
'Call to function FunctionCallStatementResultDiscarded\withSideEffects() on a separate line discards return value.',
64-
66,
74+
'Call to function FunctionCallStatementResultDiscardedPhp85\withSideEffects() on a separate line discards return value.',
75+
27,
6576
],
6677
[
67-
'Call to function FunctionCallStatementResultDiscarded\canDiscard() in (void) cast but function allows discarding return value.',
68-
69,
78+
'Call to function FunctionCallStatementResultDiscardedPhp85\canDiscard() in (void) cast but function allows discarding return value.',
79+
30,
6980
],
7081
]);
7182
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php // lint >= 8.5
2+
3+
namespace FunctionCallStatementResultDiscardedPhp85;
4+
5+
#[\NoDiscard]
6+
function withSideEffects(int $i): array {
7+
echo __FUNCTION__ . "\n";
8+
return [1];
9+
}
10+
11+
function canDiscard(int $i): int
12+
{
13+
return 1;
14+
}
15+
16+
(void)withSideEffects(5);
17+
(void) canDiscard(5);
18+
19+
$canDiscardCb = 'FunctionCallStatementResultDiscardedPhp85\\canDiscard';
20+
(void) $canDiscardCb();
21+
22+
5 |> withSideEffects(...);
23+
5 |> canDiscard(...);
24+
(void) 5 |> withSideEffects(...);
25+
(void) 5 |> canDiscard(...);
26+
27+
5 |> (fn ($x) => withSideEffects($x));
28+
5 |> (fn ($x) => canDiscard($x));
29+
(void) 5 |> (fn ($x) => withSideEffects($x));
30+
(void) 5 |> (fn ($x) => canDiscard($x));

‎tests/PHPStan/Rules/Functions/data/function-call-statement-result-discarded.php‎

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php // lint >= 8.5
1+
<?php // lint >= 8.1
22

33
namespace FunctionCallStatementResultDiscarded;
44

@@ -10,8 +10,6 @@ function withSideEffects(int $i): array {
1010

1111
withSideEffects(5);
1212

13-
(void)withSideEffects(5);
14-
1513
foreach (withSideEffects(5) as $num) {
1614
var_dump($num);
1715
}
@@ -52,18 +50,6 @@ function canDiscard(int $i): int
5250
}
5351

5452
canDiscard(5);
55-
(void) canDiscard(5);
5653

5754
$canDiscardCb = 'FunctionCallStatementResultDiscarded\\canDiscard';
5855
$canDiscardCb();
59-
(void) $canDiscardCb();
60-
61-
5 |> withSideEffects(...);
62-
5 |> canDiscard(...);
63-
(void) 5 |> withSideEffects(...);
64-
(void) 5 |> canDiscard(...);
65-
66-
5 |> (fn ($x) => withSideEffects($x));
67-
5 |> (fn ($x) => canDiscard($x));
68-
(void) 5 |> (fn ($x) => withSideEffects($x));
69-
(void) 5 |> (fn ($x) => canDiscard($x));

‎tests/PHPStan/Rules/Methods/CallToMethodStatementWithNoDiscardRuleTest.php‎

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Rules\Rule;
66
use PHPStan\Rules\RuleLevelHelper;
77
use PHPStan\Testing\RuleTestCase;
8+
use PHPUnit\Framework\Attributes\RequiresPhp;
89

910
/**
1011
* @extends RuleTestCase<CallToMethodStatementWithNoDiscardRule>
@@ -28,6 +29,8 @@ protected function getRule(): Rule
2829
);
2930
}
3031

32+
// #[\NoDiscard] is an attribute, a comment on PHP 7.4
33+
#[RequiresPhp('>= 8.0.0')]
3134
public function testRule(): void
3235
{
3336
$this->analyse([__DIR__ . '/data/method-call-statement-result-discarded.php'], [
@@ -41,27 +44,35 @@ public function testRule(): void
4144
],
4245
[
4346
'Call to method MethodCallStatementResultDiscarded\ClassWithInstanceSideEffects::differentCase() on a separate line discards return value.',
44-
30,
47+
27,
4548
],
49+
]);
50+
}
51+
52+
// the (void) cast and the pipe operator are PHP 8.5 syntax
53+
#[RequiresPhp('>= 8.5.0')]
54+
public function testRulePhp85(): void
55+
{
56+
$this->analyse([__DIR__ . '/data/method-call-statement-result-discarded-php85.php'], [
4657
[
47-
'Call to method MethodCallStatementResultDiscarded\Foo::canDiscard() in (void) cast but method allows discarding return value.',
48-
45,
58+
'Call to method MethodCallStatementResultDiscardedPhp85\Foo::canDiscard() in (void) cast but method allows discarding return value.',
59+
27,
4960
],
5061
[
51-
'Call to method MethodCallStatementResultDiscarded\ClassWithInstanceSideEffects::instanceMethod() on a separate line discards return value.',
52-
47,
62+
'Call to method MethodCallStatementResultDiscardedPhp85\ClassWithInstanceSideEffects::instanceMethod() on a separate line discards return value.',
63+
29,
5364
],
5465
[
55-
'Call to method MethodCallStatementResultDiscarded\Foo::canDiscard() in (void) cast but method allows discarding return value.',
56-
50,
66+
'Call to method MethodCallStatementResultDiscardedPhp85\Foo::canDiscard() in (void) cast but method allows discarding return value.',
67+
32,
5768
],
5869
[
59-
'Call to method MethodCallStatementResultDiscarded\ClassWithInstanceSideEffects::instanceMethod() on a separate line discards return value.',
60-
52,
70+
'Call to method MethodCallStatementResultDiscardedPhp85\ClassWithInstanceSideEffects::instanceMethod() on a separate line discards return value.',
71+
34,
6172
],
6273
[
63-
'Call to method MethodCallStatementResultDiscarded\Foo::canDiscard() in (void) cast but method allows discarding return value.',
64-
55,
74+
'Call to method MethodCallStatementResultDiscardedPhp85\Foo::canDiscard() in (void) cast but method allows discarding return value.',
75+
37,
6576
],
6677
]);
6778
}

‎tests/PHPStan/Rules/Methods/CallToStaticMethodStatementWithNoDiscardRuleTest.php‎

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Rules\Rule;
66
use PHPStan\Rules\RuleLevelHelper;
77
use PHPStan\Testing\RuleTestCase;
8+
use PHPUnit\Framework\Attributes\RequiresPhp;
89

910
/**
1011
* @extends RuleTestCase<CallToStaticMethodStatementWithNoDiscardRule>
@@ -30,6 +31,8 @@ protected function getRule(): Rule
3031
);
3132
}
3233

34+
// #[\NoDiscard] is an attribute, a comment on PHP 7.4
35+
#[RequiresPhp('>= 8.0.0')]
3336
public function testRule(): void
3437
{
3538
$this->analyse([__DIR__ . '/data/static-method-call-statement-result-discarded.php'], [
@@ -39,27 +42,35 @@ public function testRule(): void
3942
],
4043
[
4144
'Call to static method StaticMethodCallStatementResultDiscarded\ClassWithStaticSideEffects::differentCase() on a separate line discards return value.',
42-
27,
45+
25,
4346
],
47+
]);
48+
}
49+
50+
// the (void) cast and the pipe operator are PHP 8.5 syntax
51+
#[RequiresPhp('>= 8.5.0')]
52+
public function testRulePhp85(): void
53+
{
54+
$this->analyse([__DIR__ . '/data/static-method-call-statement-result-discarded-php85.php'], [
4455
[
45-
'Call to static method StaticMethodCallStatementResultDiscarded\Foo::canDiscard() in (void) cast but method allows discarding return value.',
46-
41,
56+
'Call to static method StaticMethodCallStatementResultDiscardedPhp85\Foo::canDiscard() in (void) cast but method allows discarding return value.',
57+
23,
4758
],
4859
[
49-
'Call to static method StaticMethodCallStatementResultDiscarded\ClassWithStaticSideEffects::staticMethod() on a separate line discards return value.',
50-
43,
60+
'Call to static method StaticMethodCallStatementResultDiscardedPhp85\ClassWithStaticSideEffects::staticMethod() on a separate line discards return value.',
61+
25,
5162
],
5263
[
53-
'Call to static method StaticMethodCallStatementResultDiscarded\Foo::canDiscard() in (void) cast but method allows discarding return value.',
54-
46,
64+
'Call to static method StaticMethodCallStatementResultDiscardedPhp85\Foo::canDiscard() in (void) cast but method allows discarding return value.',
65+
28,
5566
],
5667
[
57-
'Call to static method StaticMethodCallStatementResultDiscarded\ClassWithStaticSideEffects::staticMethod() on a separate line discards return value.',
58-
48,
68+
'Call to static method StaticMethodCallStatementResultDiscardedPhp85\ClassWithStaticSideEffects::staticMethod() on a separate line discards return value.',
69+
30,
5970
],
6071
[
61-
'Call to static method StaticMethodCallStatementResultDiscarded\Foo::canDiscard() in (void) cast but method allows discarding return value.',
62-
51,
72+
'Call to static method StaticMethodCallStatementResultDiscardedPhp85\Foo::canDiscard() in (void) cast but method allows discarding return value.',
73+
33,
6374
],
6475
]);
6576
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php // lint >= 8.5
2+
3+
namespace MethodCallStatementResultDiscardedPhp85;
4+
5+
class ClassWithInstanceSideEffects {
6+
#[\NoDiscard]
7+
public function instanceMethod(): array {
8+
echo __METHOD__ . "\n";
9+
return [2];
10+
}
11+
}
12+
13+
class Foo
14+
{
15+
16+
public function canDiscard(): array {
17+
return [];
18+
}
19+
20+
}
21+
22+
$o = new ClassWithInstanceSideEffects();
23+
$foo = new Foo();
24+
25+
(void)$o->instanceMethod();
26+
(void)$o?->instanceMethod();
27+
(void) $foo->canDiscard();
28+
29+
5 |> $o->instanceMethod(...);
30+
5 |> $foo->canDiscard(...);
31+
(void) 5 |> $o->instanceMethod(...);
32+
(void) 5 |> $foo->canDiscard(...);
33+
34+
5 |> (fn ($x) => $o->instanceMethod($x));
35+
5 |> (fn ($x) => $foo->canDiscard($x));
36+
(void) 5 |> (fn ($x) => $o->instanceMethod($x));
37+
(void) 5 |> (fn ($x) => $foo->canDiscard($x));

‎tests/PHPStan/Rules/Methods/data/method-call-statement-result-discarded.php‎

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php // lint >= 8.5
1+
<?php // lint >= 8.1
22

33
namespace MethodCallStatementResultDiscarded;
44

@@ -20,9 +20,6 @@ public function differentCase(): array {
2020
$o->instanceMethod();
2121
$o?->instanceMethod();
2222

23-
(void)$o->instanceMethod();
24-
(void)$o?->instanceMethod();
25-
2623
foreach ($o->instanceMethod() as $num) {
2724
var_dump($num);
2825
}
@@ -42,14 +39,3 @@ public function canDiscard(): array {
4239

4340
$foo = new Foo();
4441
$foo->canDiscard();
45-
(void) $foo->canDiscard();
46-
47-
5 |> $o->instanceMethod(...);
48-
5 |> $foo->canDiscard(...);
49-
(void) 5 |> $o->instanceMethod(...);
50-
(void) 5 |> $foo->canDiscard(...);
51-
52-
5 |> (fn ($x) => $o->instanceMethod($x));
53-
5 |> (fn ($x) => $foo->canDiscard($x));
54-
(void) 5 |> (fn ($x) => $o->instanceMethod($x));
55-
(void) 5 |> (fn ($x) => $foo->canDiscard($x));
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php // lint >= 8.5
2+
3+
namespace StaticMethodCallStatementResultDiscardedPhp85;
4+
5+
class ClassWithStaticSideEffects {
6+
#[\NoDiscard]
7+
public static function staticMethod(): array {
8+
echo __METHOD__ . "\n";
9+
return [2];
10+
}
11+
}
12+
13+
class Foo
14+
{
15+
16+
public static function canDiscard(): array {
17+
return [];
18+
}
19+
20+
}
21+
22+
(void)ClassWithStaticSideEffects::staticMethod();
23+
(void) Foo::canDiscard();
24+
25+
5 |> ClassWithStaticSideEffects::staticMethod(...);
26+
5 |> Foo::canDiscard(...);
27+
(void) 5 |> ClassWithStaticSideEffects::staticMethod(...);
28+
(void) 5 |> Foo::canDiscard(...);
29+
30+
5 |> (fn ($x) => ClassWithStaticSideEffects::staticMethod($x));
31+
5 |> (fn ($x) => Foo::canDiscard($x));
32+
(void) 5 |> (fn ($x) => ClassWithStaticSideEffects::staticMethod($x));
33+
(void) 5 |> (fn ($x) => Foo::canDiscard($x));

0 commit comments

Comments
 (0)