1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

allow short closure with never

This commit is contained in:
orklah 2022-01-06 21:12:51 +01:00
parent 46bcb626f5
commit cbb0c6398f
3 changed files with 41 additions and 0 deletions

View File

@ -464,6 +464,12 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$this->track_mutations = true;
}
if ($this->function instanceof ArrowFunction && $storage->return_type && $storage->return_type->isNever()) {
// ArrowFunction perform a return implicitly so if the return type is never, we have to suppress the error
// note: the never can only come from phpdoc. PHP will refuse short closures with never in signature
$statements_analyzer->addSuppressedIssues(['NoValue']);
}
$statements_analyzer->analyze($function_stmts, $context, $global_context, true);
if ($codebase->alter_code

View File

@ -94,6 +94,16 @@ class ScopeAnalyzer
($stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\Exit_)
) {
if (!$return_is_exit && $stmt instanceof PhpParser\Node\Stmt\Return_) {
$stmt_return_type = null;
if ($nodes && $stmt->expr) {
$stmt_return_type = $nodes->getType($stmt->expr);
}
// don't consider a return if the expression never returns (e.g. a throw inside a short closure)
if ($stmt_return_type && ($stmt_return_type->isNever() || $stmt_return_type->isEmpty())) {
return array_values(array_unique(array_merge($control_actions, [self::ACTION_END])));
}
return array_values(array_unique(array_merge($control_actions, [self::ACTION_RETURN])));
}

View File

@ -735,6 +735,31 @@ class ClosureTest extends TestCase
[],
'8.1',
],
'arrowFunctionReturnsNeverImplictly' => [
'<?php
$bar = ["foo", "bar"];
$bam = array_map(
fn(string $a) => throw new Exception($a),
$bar
);',
'assertions' => [],
'error_levels' => [],
'8.1'
],
'arrowFunctionReturnsNeverExplictly' => [
'<?php
$bar = ["foo", "bar"];
$bam = array_map(
/** @return never */
fn(string $a) => die(),
$bar
);',
'assertions' => [],
'error_levels' => [],
'8.1'
],
];
}