Skip to content

Commit

Permalink
Assert-and-throws-are-side-effects
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-worman committed Dec 10, 2024
1 parent f9c7bbd commit bde30fc
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/Rules/Pure/FunctionPurityCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ public function check(
))->identifier(sprintf('pure%s.parameterByRef', $identifier))->build();
}

if ($returnType->isVoid()->yes() && !$isConstructor) {
if (
$returnType->isVoid()->yes()
&& !$isConstructor
&& $functionReflection->getThrowType() === null
&& $functionReflection->getAsserts()->getAll() === []
) {
$errors[] = RuleErrorBuilder::message(sprintf(
'%s is marked as pure but returns void.',
$functionDescription,
Expand Down
5 changes: 5 additions & 0 deletions tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,9 @@ public function testBug11361(): void
]);
}

public function testBug12224(): void
{
$this->analyse([__DIR__ . '/data/bug-12224.php'], []);
}

}
6 changes: 6 additions & 0 deletions tests/PHPStan/Rules/Pure/PureMethodRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,10 @@ public function dataBug11207(): array
];
}

public function testBug12224(): void
{
$this->treatPhpDocTypesAsCertain = true;
$this->analyse([__DIR__ . '/data/bug-12224.php'], []);
}

}
101 changes: 101 additions & 0 deletions tests/PHPStan/Rules/Pure/data/bug-12224.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php declare(strict_types=1);

/**
* @phpstan-pure
* @throws \Exception
*/
function pureWithThrows(): void
{
throw new \Exception();
}

/**
* @phpstan-pure
* @phpstan-assert int $a
*/
function pureWithAssert(mixed $a): void
{
if (!is_int($a)) {
throw new \Exception();
}
}

/**
* @phpstan-pure
* @phpstan-assert int $a
*/
function pureWithAssertAndReturn(mixed $a): int
{
if (!is_int($a)) {
throw new \Exception();
}
return $a;
}

class A {
/**
* @phpstan-pure
* @throws \Exception
*/
public function pureWithThrows(): void
{
throw new \Exception();
}

/**
* @phpstan-pure
* @phpstan-assert int $a
*/
public function pureWithAssert(mixed $a): void
{
if (!is_int($a)) {
throw new \Exception();
}
}

/**
* @phpstan-pure
* @phpstan-assert int $a
*/
public function pureWithAssertAndReturn(mixed $a): int
{
if (!is_int($a)) {
throw new \Exception();
}
return $a;
}
}

class B {
/**
* @phpstan-pure
* @throws \Exception
*/
public static function pureWithThrows(): void
{
throw new \Exception();
}

/**
* @phpstan-pure
* @phpstan-assert int $a
*/
public static function pureWithAssert(mixed $a): void
{
if (!is_int($a)) {
throw new \Exception();
}
}

/**
* @phpstan-pure
* @phpstan-assert int $a
*/
public static function pureWithAssertAndReturn(mixed $a): int
{
if (!is_int($a)) {
throw new \Exception();
}
return $a;
}
}

0 comments on commit bde30fc

Please sign in to comment.