Skip to content

Commit

Permalink
fix implicit return type
Browse files Browse the repository at this point in the history
* fix implicit void return type errors https://psalm.dev/r/b0e397c14e
* fix void + never = null return type error https://psalm.dev/r/6f227ae9b9
* fixes vimeo#8912 and vimeo#8862
  • Loading branch information
kkmuffme committed Dec 29, 2022
1 parent 2efa6ae commit 0801442
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ public static function verifyReturnType(
&& count($inferred_return_type_parts)
&& !$did_explicitly_return
) {
// only add null if we have a return statement elsewhere and it wasn't void
// only add null if we have a return statement elsewhere and it wasn't void or never
foreach ($inferred_return_type_parts as $inferred_return_type_part) {
if (!$inferred_return_type_part->isVoid()) {
if (!$inferred_return_type_part->isVoid() && !$inferred_return_type_part->isNever()) {
$atomic_null = new TNull(true);
$inferred_return_type_parts[] = new Union([$atomic_null]);
break;
Expand Down Expand Up @@ -233,6 +233,22 @@ public static function verifyReturnType(
return null;
}

// only now after non-implicit things are checked
if ($function_returns_implicitly) {
$inferred_return_type_parts[] = Type::getVoid();
}

$inferred_return_type_parts_with_never = $inferred_return_type_parts;
$number_of_types = count($inferred_return_type_parts);
// we filter TNever that have no bearing on the return type
if ($number_of_types > 1) {
$inferred_return_type_parts = array_filter(
$inferred_return_type_parts,
static fn(Union $union_type): bool => !$union_type->isNever()
);
}
$inferred_return_type_parts = array_values($inferred_return_type_parts);

$inferred_return_type = $inferred_return_type_parts
? Type::combineUnionTypeArray($inferred_return_type_parts, $codebase)
: Type::getVoid();
Expand All @@ -241,6 +257,13 @@ public static function verifyReturnType(
$inferred_return_type = Type::getNever();
}

// void + never = null, so we need to check this separately
if ($inferred_return_type_parts_with_never !== $inferred_return_type_parts && !$function_always_exits) {
$inferred_return_type_with_never = Type::combineUnionTypeArray($inferred_return_type_parts_with_never, $codebase);
} else {
$inferred_return_type_with_never = $inferred_return_type;
}

$inferred_yield_type = $inferred_yield_types
? Type::combineUnionTypeArray($inferred_yield_types, $codebase)
: null;
Expand Down Expand Up @@ -491,7 +514,7 @@ public static function verifyReturnType(

$union_comparison_results = new TypeComparisonResult();

if ($declared_return_type->explicit_never === true && $inferred_return_type->explicit_never === false) {
if ($declared_return_type->explicit_never === true && $inferred_return_type_with_never->explicit_never === false) {
if (IssueBuffer::accepts(
new MoreSpecificReturnType(
'The declared return type \'' . $declared_return_type->getId() . '|never\' for '
Expand Down

0 comments on commit 0801442

Please sign in to comment.