Skip to content

Commit

Permalink
Merge pull request #7260 from orklah/6691
Browse files Browse the repository at this point in the history
forbid calling impure callable in immutable context
  • Loading branch information
orklah committed Jan 1, 2022
2 parents 8dc1a31 + 8e5c9f0 commit 2a6f122
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/Psalm/Context.php
Expand Up @@ -353,11 +353,13 @@ class Context

/**
* @var bool
* Set by @psalm-immutable
*/
public $mutation_free = false;

/**
* @var bool
* Set by @psalm-external-mutation-free
*/
public $external_mutation_free = false;

Expand Down
Expand Up @@ -643,7 +643,7 @@ private static function getAnalyzeNamedExpression(
}

if ($var_type_part instanceof TClosure || $var_type_part instanceof TCallable) {
if (!$var_type_part->is_pure && $context->pure) {
if (!$var_type_part->is_pure && ($context->pure || $context->mutation_free)) {
IssueBuffer::maybeAdd(
new ImpureFunctionCall(
'Cannot call an impure function from a mutation-free context',
Expand Down
32 changes: 32 additions & 0 deletions tests/PureAnnotationTest.php
Expand Up @@ -876,6 +876,38 @@ function testImpure(): void
',
'error_message' => 'ImpureMethodCall',
],
'impureCallableInImmutableContext' => [
'<?php
/**
* @psalm-immutable
*/
class Either
{
/**
* @psalm-param callable $_
*/
public function fold($_): void
{
$_();
}
}
class Whatever
{
public function __construct()
{
$either = new Either();
$either->fold(
function (): void {}
);
}
}
new Whatever();
',
'error_message' => 'ImpureFunctionCall',
],
];
}
}
2 changes: 1 addition & 1 deletion tests/Template/ClassTemplateTest.php
Expand Up @@ -2991,7 +2991,7 @@ public function toString(): string
/**
* @psalm-template TResult
* @psalm-param callable(self::READ_UNCOMMITTED): TResult $readUncommitted
* @psalm-param pure-callable(self::READ_UNCOMMITTED): TResult $readUncommitted
* @psalm-return TResult
*/
public function resolve(callable $readUncommitted) {
Expand Down

0 comments on commit 2a6f122

Please sign in to comment.