1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Merge pull request #9783 from robchett/remove_MixedInferredReturnType

Remove MixedInferredReturnType
This commit is contained in:
orklah 2023-11-13 21:29:56 +01:00 committed by GitHub
commit 3efb292039
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 25 additions and 166 deletions

View File

@ -12,8 +12,11 @@
- [BC] The only optional boolean parameter of `TKeyedArray::getGenericArrayType` was removed, and was replaced with a string parameter with a different meaning.
- [BC] The `TDependentListKey` type was removed and replaced with an optional property of the `TIntRange` type.
-
- [BC] `TCallableArray` and `TCallableList` removed and replaced with `TCallableKeyedArray`.
- [BC] Class `Psalm\Issue\MixedInferredReturnType` was removed
- [BC] Value of constant `Psalm\Type\TaintKindGroup::ALL_INPUT` changed to reflect new `TaintKind::INPUT_SLEEP` and `TaintKind::INPUT_XPATH` have been added. Accordingly, default values for `$taint` parameters of `Psalm\Codebase::addTaintSource()` and `Psalm\Codebase::addTaintSink()` have been changed as well.
- [BC] Property `Config::$shepherd_host` was replaced with `Config::$shepherd_endpoint`

View File

@ -334,7 +334,6 @@
<xs:element name="MixedAssignment" type="IssueHandlerType" minOccurs="0" />
<xs:element name="MixedClone" type="ArgumentIssueHandlerType" minOccurs="0" />
<xs:element name="MixedFunctionCall" type="IssueHandlerType" minOccurs="0" />
<xs:element name="MixedInferredReturnType" type="IssueHandlerType" minOccurs="0" />
<xs:element name="MixedMethodCall" type="IssueHandlerType" minOccurs="0" />
<xs:element name="MixedOperand" type="IssueHandlerType" minOccurs="0" />
<xs:element name="MixedPropertyAssignment" type="IssueHandlerType" minOccurs="0" />

View File

@ -262,7 +262,6 @@ Level 5 and above allows a more non-verifiable code, and higher levels are even
- [MixedAssignment](issues/MixedAssignment.md)
- [MixedClone](issues/MixedClone.md)
- [MixedFunctionCall](issues/MixedFunctionCall.md)
- [MixedInferredReturnType](issues/MixedInferredReturnType.md)
- [MixedMethodCall](issues/MixedMethodCall.md)
- [MixedOperand](issues/MixedOperand.md)
- [MixedPropertyAssignment](issues/MixedPropertyAssignment.md)

View File

@ -134,7 +134,6 @@
- [MixedAssignment](issues/MixedAssignment.md)
- [MixedClone](issues/MixedClone.md)
- [MixedFunctionCall](issues/MixedFunctionCall.md)
- [MixedInferredReturnType](issues/MixedInferredReturnType.md)
- [MixedMethodCall](issues/MixedMethodCall.md)
- [MixedOperand](issues/MixedOperand.md)
- [MixedPropertyAssignment](issues/MixedPropertyAssignment.md)

View File

@ -1,11 +0,0 @@
# MixedInferredReturnType
Emitted when Psalm cannot determine a function's return type
```php
<?php
function foo() : int {
return $GLOBALS['foo'];
}
```

View File

@ -156,7 +156,6 @@ final class Config
'MixedArrayTypeCoercion',
'MixedAssignment',
'MixedFunctionCall',
'MixedInferredReturnType',
'MixedMethodCall',
'MixedOperand',
'MixedPropertyFetch',

View File

@ -40,7 +40,6 @@ use Psalm\Issue\LessSpecificReturnType;
use Psalm\Issue\MismatchingDocblockReturnType;
use Psalm\Issue\MissingClosureReturnType;
use Psalm\Issue\MissingReturnType;
use Psalm\Issue\MixedInferredReturnType;
use Psalm\Issue\MixedReturnTypeCoercion;
use Psalm\Issue\MoreSpecificReturnType;
use Psalm\Issue\UnresolvableConstant;
@ -516,17 +515,6 @@ final class ReturnTypeAnalyzer
}
if ($inferred_return_type->hasMixed()) {
if (IssueBuffer::accepts(
new MixedInferredReturnType(
'Could not verify return type \'' . $declared_return_type . '\' for ' .
$cased_method_id,
$return_type_location,
),
$suppressed_issues,
)) {
return false;
}
return null;
}

View File

@ -1,13 +0,0 @@
<?php
declare(strict_types=1);
namespace Psalm\Issue;
final class MixedInferredReturnType extends CodeIssue implements MixedIssue
{
public const ERROR_LEVEL = 1;
public const SHORTCODE = 47;
use MixedIssueTrait;
}

View File

@ -2259,9 +2259,6 @@ class ArrayAssignmentTest extends TestCase
],
'mergeWithDeeplyNestedArray' => [
'code' => '<?php
/**
* @psalm-suppress MixedInferredReturnType
*/
function getTwoPartsLocale(array $cache, string $a, string $b) : string
{
if (!isset($cache[$b])) {

View File

@ -301,7 +301,6 @@ class CacheTest extends TestCase
'/src/A.php' => [
"UndefinedThisPropertyFetch: Instance property A::\$foo is not defined",
"MixedReturnStatement: Could not infer a return type",
"MixedInferredReturnType: Could not verify return type 'string' for A::bar",
],
],
],

View File

@ -1917,7 +1917,7 @@ class CallableTest extends TestCase
}
}',
'error_message' => 'InvalidFunctionCall',
'ignored_issues' => ['UndefinedClass', 'MixedInferredReturnType'],
'ignored_issues' => ['UndefinedClass'],
],
'undefinedCallableMethodFullString' => [
'code' => '<?php

View File

@ -341,7 +341,6 @@ class ClassTest extends TestCase
'assertions' => [],
'ignored_issues' => [
'UndefinedClass',
'MixedInferredReturnType',
'InvalidArgument',
],
],
@ -356,7 +355,6 @@ class ClassTest extends TestCase
'assertions' => [],
'ignored_issues' => [
'UndefinedClass',
'MixedInferredReturnType',
'InvalidArgument',
],
],

View File

@ -290,10 +290,6 @@ class DocumentationTest extends TestCase
$ignored_issues = ['InvalidReturnStatement'];
break;
case 'MixedInferredReturnType':
$ignored_issues = ['MixedReturnStatement'];
break;
case 'MixedStringOffsetAssignment':
$ignored_issues = ['MixedAssignment'];
break;

View File

@ -917,7 +917,7 @@ class FunctionCallTest extends TestCase
'$porta' => 'false|int|null',
'$porte' => 'false|int|null',
],
'ignored_issues' => ['MixedReturnStatement', 'MixedInferredReturnType'],
'ignored_issues' => ['MixedReturnStatement'],
],
'parseUrlComponent' => [
'code' => '<?php

View File

@ -90,7 +90,7 @@ class JsonOutputTest extends TestCase
function fooFoo(int $a): int {
return $b + 1;
}',
'error_count' => 5,
'error_count' => 4,
'message' => 'Cannot find referenced variable $b',
'line' => 3,
'error' => '$b',
@ -100,7 +100,7 @@ class JsonOutputTest extends TestCase
function fooFoo(Badger\Bodger $a): Badger\Bodger {
return $a;
}',
'error_count' => 3,
'error_count' => 2,
'message' => 'Class, interface or enum named Badger\\Bodger does not exist',
'line' => 2,
'error' => 'Badger\\Bodger',

View File

@ -398,7 +398,7 @@ class MagicPropertyTest extends TestCase
}
}',
'assertions' => [],
'ignored_issues' => ['MixedReturnStatement', 'MixedInferredReturnType'],
'ignored_issues' => ['MixedReturnStatement'],
],
'overrideInheritedProperty' => [
'code' => '<?php

View File

@ -1150,7 +1150,7 @@ class MethodCallTest extends TestCase
}
}',
'assertions' => [],
'ignored_issues' => ['MixedReturnStatement', 'MixedInferredReturnType'],
'ignored_issues' => ['MixedReturnStatement'],
'php_version' => '8.0',
],
'nullsafeShortCircuit' => [
@ -1342,7 +1342,7 @@ class MethodCallTest extends TestCase
}
}',
'error_message' => 'LessSpecificReturnStatement',
'ignored_issues' => ['MixedInferredReturnType', 'MixedReturnStatement', 'MixedMethodCall'],
'ignored_issues' => ['MixedReturnStatement', 'MixedMethodCall'],
],
'undefinedVariableStaticCall' => [
'code' => '<?php

View File

@ -81,7 +81,6 @@ class ReferenceConstraintTest extends TestCase
'MixedAssignment',
'MixedArrayAccess',
'MixedReturnStatement',
'MixedInferredReturnType',
'MixedOperand',
],
],

View File

@ -755,28 +755,6 @@ class ReportOutputTest extends TestCase
'taint_trace' => null,
'other_references' => null,
],
[
'severity' => 'error',
'line_from' => 2,
'line_to' => 2,
'type' => 'MixedInferredReturnType',
'message' => 'Could not verify return type \'null|string\' for psalmCanVerify',
'file_name' => 'somefile.php',
'file_path' => 'somefile.php',
'snippet' => 'function psalmCanVerify(int $your_code): ?string {',
'selected_text' => '?string',
'from' => 47,
'to' => 54,
'snippet_from' => 6,
'snippet_to' => 56,
'column_from' => 42,
'column_to' => 49,
'error_level' => 1,
'shortcode' => 47,
'link' => 'https://psalm.dev/047',
'taint_trace' => null,
'other_references' => null,
],
[
'severity' => 'error',
'line_from' => 8,
@ -854,7 +832,7 @@ class ReportOutputTest extends TestCase
];
$report_options = ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.json'])[0];
$fixable_issue_counts = ['MixedInferredReturnType' => 1];
$fixable_issue_counts = [];
$report = new JsonReport(
$issues_data,
@ -902,22 +880,6 @@ class ReportOutputTest extends TestCase
'type' => 'CODE_SMELL',
'severity' => 'CRITICAL',
],
[
'engineId' => 'Psalm',
'ruleId' => 'MixedInferredReturnType',
'primaryLocation' => [
'message' => 'Could not verify return type \'null|string\' for psalmCanVerify',
'filePath' => 'somefile.php',
'textRange' => [
'startLine' => 2,
'endLine' => 2,
'startColumn' => 41,
'endColumn' => 48,
],
],
'type' => 'CODE_SMELL',
'severity' => 'CRITICAL',
],
[
'engineId' => 'Psalm',
'ruleId' => 'UndefinedConstant',
@ -972,7 +934,6 @@ class ReportOutputTest extends TestCase
<<<'EOF'
somefile.php:3:10:error - UndefinedVariable: Cannot find referenced variable $as_you_____type (see https://psalm.dev/024)
somefile.php:3:10:error - MixedReturnStatement: Could not infer a return type (see https://psalm.dev/138)
somefile.php:2:42:error - MixedInferredReturnType: Could not verify return type 'null|string' for psalmCanVerify (see https://psalm.dev/047)
somefile.php:8:6:error - UndefinedConstant: Const CHANGE_ME is not defined (see https://psalm.dev/020)
somefile.php:17:6:warning - PossiblyUndefinedGlobalVariable: Possibly undefined global variable $a, first seen on line 11 (see https://psalm.dev/126)
@ -991,7 +952,6 @@ class ReportOutputTest extends TestCase
<<<'EOF'
somefile.php:3: [E0001] UndefinedVariable: Cannot find referenced variable $as_you_____type (column 10)
somefile.php:3: [E0001] MixedReturnStatement: Could not infer a return type (column 10)
somefile.php:2: [E0001] MixedInferredReturnType: Could not verify return type 'null|string' for psalmCanVerify (column 42)
somefile.php:8: [E0001] UndefinedConstant: Const CHANGE_ME is not defined (column 6)
somefile.php:17: [W0001] PossiblyUndefinedGlobalVariable: Possibly undefined global variable $a, first seen on line 11 (column 6)
@ -1015,9 +975,6 @@ class ReportOutputTest extends TestCase
ERROR: MixedReturnStatement - somefile.php:3:10 - Could not infer a return type (see https://psalm.dev/138)
return $as_you_____type;
ERROR: MixedInferredReturnType - somefile.php:2:42 - Could not verify return type 'null|string' for psalmCanVerify (see https://psalm.dev/047)
function psalmCanVerify(int $your_code): ?string {
ERROR: UndefinedConstant - somefile.php:8:6 - Const CHANGE_ME is not defined (see https://psalm.dev/020)
echo CHANGE_ME;
@ -1046,9 +1003,6 @@ class ReportOutputTest extends TestCase
ERROR: MixedReturnStatement - somefile.php:3:10 - Could not infer a return type (see https://psalm.dev/138)
return $as_you_____type;
ERROR: MixedInferredReturnType - somefile.php:2:42 - Could not verify return type 'null|string' for psalmCanVerify (see https://psalm.dev/047)
function psalmCanVerify(int $your_code): ?string {
ERROR: UndefinedConstant - somefile.php:8:6 - Const CHANGE_ME is not defined (see https://psalm.dev/020)
echo CHANGE_ME;
@ -1074,9 +1028,6 @@ class ReportOutputTest extends TestCase
ERROR: MixedReturnStatement - somefile.php:3:10 - Could not infer a return type (see https://psalm.dev/138)
ERROR: MixedInferredReturnType - somefile.php:2:42 - Could not verify return type 'null|string' for psalmCanVerify (see https://psalm.dev/047)
ERROR: UndefinedConstant - somefile.php:8:6 - Const CHANGE_ME is not defined (see https://psalm.dev/020)
@ -1135,15 +1086,14 @@ class ReportOutputTest extends TestCase
<<<'EOF'
FILE: somefile.php
+----------+------+---------------------------------+---------------------------------------------------------------+
| SEVERITY | LINE | ISSUE | DESCRIPTION |
+----------+------+---------------------------------+---------------------------------------------------------------+
| ERROR | 3 | UndefinedVariable | Cannot find referenced variable $as_you_____type |
| ERROR | 3 | MixedReturnStatement | Could not infer a return type |
| ERROR | 2 | MixedInferredReturnType | Could not verify return type 'null|string' for psalmCanVerify |
| ERROR | 8 | UndefinedConstant | Const CHANGE_ME is not defined |
| INFO | 17 | PossiblyUndefinedGlobalVariable | Possibly undefined global variable $a, first seen on line 11 |
+----------+------+---------------------------------+---------------------------------------------------------------+
+----------+------+---------------------------------+--------------------------------------------------------------+
| SEVERITY | LINE | ISSUE | DESCRIPTION |
+----------+------+---------------------------------+--------------------------------------------------------------+
| ERROR | 3 | UndefinedVariable | Cannot find referenced variable $as_you_____type |
| ERROR | 3 | MixedReturnStatement | Could not infer a return type |
| ERROR | 8 | UndefinedConstant | Const CHANGE_ME is not defined |
| INFO | 17 | PossiblyUndefinedGlobalVariable | Possibly undefined global variable $a, first seen on line 11 |
+----------+------+---------------------------------+--------------------------------------------------------------+
EOF,
$this->toUnixLineEndings(IssueBuffer::getOutput(IssueBuffer::getIssuesData(), $compact_report_options)),
@ -1166,9 +1116,6 @@ class ReportOutputTest extends TestCase
<file name="somefile.php">
<error line="3" column="10" severity="error" message="MixedReturnStatement: Could not infer a return type"/>
</file>
<file name="somefile.php">
<error line="2" column="42" severity="error" message="MixedInferredReturnType: Could not verify return type &apos;null|string&apos; for psalmCanVerify"/>
</file>
<file name="somefile.php">
<error line="8" column="6" severity="error" message="UndefinedConstant: Const CHANGE_ME is not defined"/>
</file>
@ -1199,8 +1146,8 @@ class ReportOutputTest extends TestCase
$this->assertSame(
<<<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<testsuites failures="4" errors="0" name="psalm" tests="5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/junit-team/junit5/r5.5.1/platform-tests/src/test/resources/jenkins-junit.xsd">
<testsuite name="somefile.php" failures="4" errors="0" tests="5">
<testsuites failures="3" errors="0" name="psalm" tests="4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/junit-team/junit5/r5.5.1/platform-tests/src/test/resources/jenkins-junit.xsd">
<testsuite name="somefile.php" failures="3" errors="0" tests="4">
<testcase name="somefile.php:3" classname="UndefinedVariable" assertions="1">
<failure type="UndefinedVariable">message: Cannot find referenced variable $as_you_____type
type: UndefinedVariable
@ -1219,16 +1166,6 @@ class ReportOutputTest extends TestCase
line: 3
column_from: 10
column_to: 26
</failure>
</testcase>
<testcase name="somefile.php:2" classname="MixedInferredReturnType" assertions="1">
<failure type="MixedInferredReturnType">message: Could not verify return type 'null|string' for psalmCanVerify
type: MixedInferredReturnType
snippet: function psalmCanVerify(int $your_code): ?string {
selected_text: ?string
line: 2
column_from: 42
column_to: 49
</failure>
</testcase>
<testcase name="somefile.php:8" classname="UndefinedConstant" assertions="1">
@ -1283,7 +1220,6 @@ class ReportOutputTest extends TestCase
$expected_output = <<<'EOF'
::error file=somefile.php,line=3,col=10,title=UndefinedVariable::somefile.php:3:10: UndefinedVariable: Cannot find referenced variable $as_you_____type (see https://psalm.dev/024)
::error file=somefile.php,line=3,col=10,title=MixedReturnStatement::somefile.php:3:10: MixedReturnStatement: Could not infer a return type (see https://psalm.dev/138)
::error file=somefile.php,line=2,col=42,title=MixedInferredReturnType::somefile.php:2:42: MixedInferredReturnType: Could not verify return type 'null|string' for psalmCanVerify (see https://psalm.dev/047)
::error file=somefile.php,line=8,col=6,title=UndefinedConstant::somefile.php:8:6: UndefinedConstant: Const CHANGE_ME is not defined (see https://psalm.dev/020)
::warning file=somefile.php,line=17,col=6,title=PossiblyUndefinedGlobalVariable::somefile.php:17:6: PossiblyUndefinedGlobalVariable: Possibly undefined global variable $a, first seen on line 11 (see https://psalm.dev/126)
@ -1301,7 +1237,6 @@ class ReportOutputTest extends TestCase
$report_options = new ReportOptions();
$report_options->format = Report::TYPE_COUNT;
$expected_output = <<<'EOF'
MixedInferredReturnType: 1
MixedReturnStatement: 1
PossiblyUndefinedGlobalVariable: 1
UndefinedConstant: 1

View File

@ -1380,14 +1380,6 @@ class ReturnTypeTest extends TestCase
}',
'error_message' => 'MissingReturnType',
],
'mixedInferredReturnType' => [
'code' => '<?php
function fooFoo(array $arr): string {
/** @psalm-suppress MixedReturnStatement */
return array_pop($arr);
}',
'error_message' => 'MixedInferredReturnType',
],
'mixedInferredReturnStatement' => [
'code' => '<?php
function fooFoo(array $arr): string {
@ -1395,14 +1387,6 @@ class ReturnTypeTest extends TestCase
}',
'error_message' => 'MixedReturnStatement',
],
'invalidReturnTypeClass' => [
'code' => '<?php
function fooFoo(): A {
return new A;
}',
'error_message' => 'UndefinedClass',
'ignored_issues' => ['MixedInferredReturnType'],
],
'invalidClassOnCall' => [
'code' => '<?php
/**
@ -1414,7 +1398,7 @@ class ReturnTypeTest extends TestCase
fooFoo()->bar();',
'error_message' => 'UndefinedClass',
'ignored_issues' => ['MixedInferredReturnType', 'MixedReturnStatement'],
'ignored_issues' => ['MixedReturnStatement'],
],
'returnArrayOfNullableInvalid' => [
'code' => '<?php

View File

@ -406,7 +406,6 @@ class FunctionClassStringTemplateTest extends TestCase
* @psalm-template RequestedType
* @psalm-param class-string<RequestedType> $className
* @psalm-return RequestedType&MockObject
* @psalm-suppress MixedInferredReturnType
* @psalm-suppress MixedReturnStatement
*/
function mockHelper(string $className)
@ -444,7 +443,6 @@ class FunctionClassStringTemplateTest extends TestCase
* @psalm-template RequestedType
* @psalm-param class-string<RequestedType> $className
* @psalm-return RequestedType&MockObject
* @psalm-suppress MixedInferredReturnType
* @psalm-suppress MixedReturnStatement
*/
function mockHelper(string $className)
@ -482,7 +480,6 @@ class FunctionClassStringTemplateTest extends TestCase
* @psalm-template RequestedType
* @psalm-param class-string<RequestedType> $className
* @psalm-return MockObject&RequestedType
* @psalm-suppress MixedInferredReturnType
* @psalm-suppress MixedReturnStatement
*/
function mockHelper(string $className)

View File

@ -1336,7 +1336,6 @@ class FunctionTemplateTest extends TestCase
* @param E $e
* @param mixed $d
* @return ?E
* @psalm-suppress MixedInferredReturnType
*/
function reduce_values($e, $d) {
if (rand(0, 1)) {
@ -1359,7 +1358,6 @@ class FunctionTemplateTest extends TestCase
* @param E $e
* @param mixed $d
* @return ?E
* @psalm-suppress MixedInferredReturnType
*/
function reduce_values($e, $d)
{

View File

@ -79,7 +79,7 @@ class ArrayKeyExistsTest extends TestCase
}
}',
'assertions' => [],
'ignored_issues' => ['MixedReturnStatement', 'MixedInferredReturnType'],
'ignored_issues' => ['MixedReturnStatement'],
],
'assertSelfClassConstantOffsetsInFunction' => [
'code' => '<?php
@ -100,7 +100,7 @@ class ArrayKeyExistsTest extends TestCase
}
}',
'assertions' => [],
'ignored_issues' => ['MixedReturnStatement', 'MixedInferredReturnType'],
'ignored_issues' => ['MixedReturnStatement'],
],
'assertNamedClassConstantOffsetsInFunction' => [
'code' => '<?php
@ -121,7 +121,7 @@ class ArrayKeyExistsTest extends TestCase
return C::ARR[$key]["foo"];
}',
'assertions' => [],
'ignored_issues' => ['MixedReturnStatement', 'MixedInferredReturnType'],
'ignored_issues' => ['MixedReturnStatement'],
],
'possiblyUndefinedArrayAccessWithArrayKeyExists' => [
'code' => '<?php

View File

@ -63,7 +63,6 @@ class AssignmentInConditionalTest extends TestCase
'assertOnRemainderOfArray' => [
'code' => '<?php
/**
* @psalm-suppress MixedInferredReturnType
* @psalm-suppress MixedReturnStatement
*/
function foo(string $file_name) : int {

View File

@ -1383,7 +1383,6 @@ class ConditionalTest extends TestCase
'code' => '<?php
/**
* @psalm-suppress MixedReturnStatement
* @psalm-suppress MixedInferredReturnType
*/
function foo() : array {
return filter_input(INPUT_POST, "some_var") ?? [];
@ -1727,7 +1726,6 @@ class ConditionalTest extends TestCase
/**
* @psalm-suppress MixedArrayAccess
* @psalm-suppress MixedReturnStatement
* @psalm-suppress MixedInferredReturnType
* @psalm-suppress MixedArrayAssignment
*/
public function foo() : stdClass {
@ -2112,7 +2110,6 @@ class ConditionalTest extends TestCase
/**
* @psalm-suppress MixedReturnStatement
* @psalm-suppress MixedInferredReturnType
* @psalm-suppress MixedArrayAccess
*/
public static function get(string $k1, string $k2) : ?string {

View File

@ -842,7 +842,6 @@ class TypeAlgebraTest extends TestCase
return "LTR";
}',
'assertions' => [],
'ignored_issues' => ['MixedInferredReturnType'],
],
'grandParentInstanceofConfusion' => [
'code' => '<?php

View File

@ -1352,7 +1352,6 @@ class UnusedVariableTest extends TestCase
'usedInUndefinedFunction' => [
'code' => '<?php
/**
* @psalm-suppress MixedInferredReturnType
* @psalm-suppress MixedReturnStatement
*/
function test(): string {
@ -2231,7 +2230,6 @@ class UnusedVariableTest extends TestCase
'code' => '<?php
/**
* @psalm-suppress MixedReturnStatement
* @psalm-suppress MixedInferredReturnType
*/
function foo(array $data) : array {
$output = [];