[ 'code' => ' [ 'code' => ' [ '$a' => 'non-empty-list', ], ], 'arrayMergeArgumentUnpacking' => [ 'code' => ' [ '$b===' => 'list{1, 2}', ], ], 'preserveTypesWhenUnpacking' => [ 'code' => '> */ function getData(): array { return [ ["a", "b"], ["c", "d"] ]; } /** * @return array */ function f1(): array { $data = getData(); return array_merge($data[0], $data[1]); } /** * @return array */ function f2(): array { $data = getData(); return array_merge(...$data); } /** * @return array */ function f3(): array { $data = getData(); return array_merge([], ...$data); }', ], 'unpackArg' => [ 'code' => ' */ function Baz(string ...$c) { Foo(...$c); return $c; }', ], 'unpackByRefArg' => [ 'code' => ' [ '$y' => 'int', '$z' => 'array', ], ], 'callMapClassOptionalArg' => [ 'code' => 'invoke(null, "cool");', ], 'sortFunctions' => [ 'code' => ' 5, "a" => 8]; ksort($a); $b = ["b" => 5, "a" => 8]; sort($b); $c = []; sort($c); ', 'assertions' => [ '$a' => 'array{a: int, b: int}', '$b' => 'non-empty-list', '$c' => 'list', ], ], 'arrayModificationFunctions' => [ 'code' => ' 5, "a" => 8]; array_unshift($a, (bool)rand(0, 1)); $b = ["b" => 5, "a" => 8]; array_push($b, (bool)rand(0, 1)); ', 'assertions' => [ '$a' => 'non-empty-array', '$b' => 'non-empty-array', ], ], 'byRefArgAssignment' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' $arr */ function foo(array $arr) : void { } /** @return array */ function bar() : array { return []; } /** @psalm-suppress ArgumentTypeCoercion */ foo(bar());', ], 'allowArrayScalarForArrayStringWithArgumentTypeCoercionIgnored' => [ 'code' => ' $arr */ function foo(array $arr) : void {} /** @return array */ function bar() : array { return []; } /** @psalm-suppress ArgumentTypeCoercion */ foo(bar());', ], 'unpackObjectlikeListArgs' => [ 'code' => ' [ 'code' => ' [ '$a' => 'non-empty-list' ] ], 'iterableSplat' => [ 'code' => ' $args */ function foo(iterable $args): int { return intval(...$args); } /** @param ArrayIterator $args */ function bar(ArrayIterator $args): int { return intval(...$args); }', ], 'unpackListWithOptional' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ 'code' => ' "hello", "age" => 5]; takesArguments(...$args);', 'assertions' => [], 'ignored_issues' => [], 'php_version' => '8.0' ], 'useNamedVariadicArguments' => [ 'code' => ' [], 'ignored_issues' => [], 'php_version' => '8.0' ], 'useUnpackedNamedVariadicArguments' => [ 'code' => ' 5]);', 'assertions' => [], 'ignored_issues' => [], 'php_version' => '8.0' ], 'variadicArgsOptional' => [ 'code' => ' [ 'code' => ' [], 'ignored_issues' => [], 'php_version' => '8.0' ], 'variadicArgumentWithNoNamedArgumentsIsList' => [ 'code' => ' */ public function foo(int ...$values): array { return $values; } } ', ], 'SealedAcceptSealed' => [ 'code' => ' "str"]; a($sealed); ', ], 'variadicCallbackArgsCountMatch' => [ 'code' => ' [ 'code' => ' [ 'code' => ' 'InvalidArgument', ], 'possiblyInvalidArgument' => [ 'code' => ' 'PossiblyInvalidArgument', ], 'possiblyInvalidArgumentWithOverlap' => [ 'code' => ' 'PossiblyInvalidArgument', ], 'possiblyInvalidArgumentWithMixed' => [ 'code' => ' 'PossiblyInvalidArgument', ], 'expectsNonNullAndPassedPossiblyNull' => [ 'code' => ' 'PossiblyNullArgument' ], 'useInvalidNamedArgument' => [ 'code' => ' 'InvalidNamedArgument' ], 'usePositionalArgAfterNamed' => [ 'code' => ' 'InvalidNamedArgument' ], 'useUnpackedInvalidNamedArgument' => [ 'code' => ' 'InvalidNamedArgument', 'ignored_issues' => [], 'php_version' => '8.0' ], 'noNamedArgsMethod' => [ 'code' => ' 'NamedArgumentNotAllowed', ], 'noNamedArgsFunction' => [ 'code' => ' 'NamedArgumentNotAllowed', ], 'arrayWithoutAllNamedParameters' => [ 'code' => ' 'MixedArgument', 'ignored_issues' => [], 'php_version' => '8.0' ], 'arrayWithoutAllNamedParametersSuppressMixed' => [ 'code' => ' 'TooFewArguments', 'ignored_issues' => [], 'php_version' => '8.0' ], 'wrongTypeVariadicArguments' => [ 'code' => ' 'InvalidScalarArgument', 'ignored_issues' => [], 'php_version' => '8.0' ], 'byrefVarSetsPossible' => [ 'code' => ' 'PossiblyUndefinedGlobalVariable', ], 'overwriteNamedParam' => [ 'code' => ' 'InvalidNamedArgument', 'ignored_issues' => [], 'php_version' => '8.0' ], 'overwriteOrderedNamedParam' => [ 'code' => ' 'InvalidNamedArgument', 'ignored_issues' => [], 'php_version' => '8.0' ], 'overwriteOrderedWithUnpackedNamedParam' => [ 'code' => ' 2]);', 'error_message' => 'InvalidNamedArgument', 'ignored_issues' => [], 'php_version' => '8.0' ], 'variadicArgumentIsNotList' => [ 'code' => ' */ function foo(int ...$values): array { return $values; } ', 'error_message' => 'MixedReturnTypeCoercion', ], 'preventUnpackingPossiblyIterable' => [ 'code' => '|object */ $test = [1, 2]; foo(...$test); ', 'error_message' => 'PossiblyInvalidArgument' ], 'SKIPPED-preventUnpackingPossiblyArray' => [ 'code' => '|object */ $test = [1, 2]; foo(...$test); ', 'error_message' => 'PossiblyInvalidArgument' ], 'noNamedArguments' => [ 'code' => ' 'NamedArgumentNotAllowed', 'ignored_issues' => [], 'php_version' => '8.0', ], 'noNamedArgumentsUnpackIterable' => [ 'code' => ' */ $test = ["arg1" => 1, "arg2" => 2]; foo(...$test); ', 'error_message' => 'NamedArgumentNotAllowed', 'ignored_issues' => [], 'php_version' => '8.0', ], 'variadicArgumentWithNoNamedArgumentsPreventsPassingArrayWithStringKey' => [ 'code' => ' */ function foo(int ...$values): array { return $values; } foo(...["a" => 0]); ', 'error_message' => 'NamedArgumentNotAllowed', ], 'unpackNonArrayKeyIterable' => [ 'code' => ' */ $test = null; foo(...$test); ', 'error_message' => 'InvalidArgument', ], 'numericStringIsNotNonFalsy' => [ 'code' => ' 'ArgumentTypeCoercion', ], 'objectIsNotObjectWithProperties' => [ 'code' => ' 42]; } /** @param object{hmm:float} $_o */ function takesObject($_o): void {} takesObject(makeObj()); // expected: ArgumentTypeCoercion ', 'error_message' => 'ArgumentTypeCoercion', ], 'objectRedundantCast' => [ 'code' => ' 42]; } function takesObject(object $_o): void {} takesObject((object)makeObj()); // expected: RedundantCast ', 'error_message' => 'RedundantCast', ], 'MissingMandatoryParamWithNamedParams' => [ 'code' => ' 'TooFewArguments', ], 'SealedRefuseUnsealed' => [ 'code' => ' 'InvalidArgument', ], 'SealedRefuseSealedExtra' => [ 'code' => ' "str", "somethingElse" => "test"]; a($sealedExtraKeys); ', 'error_message' => 'InvalidArgument - src' . DIRECTORY_SEPARATOR . 'somefile.php:8:23 - Argument 1 of a expects array{test: string}, but array{somethingElse: \'test\', test: \'str\'} with additional array shape fields (somethingElse) was provided', ], 'callbackArgsCountMismatch' => [ 'code' => ' 'InvalidScalarArgument', ], 'callableArgsCountMismatch' => [ 'code' => ' 'InvalidScalarArgument', ], ]; } }