From 00c2fef25d8c038d6faa0c6b5df027d0dd6355b2 Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Sat, 9 Mar 2024 23:10:08 +0100 Subject: [PATCH] Forbid named arguments for ArrayAcccess methods Fixes vimeo/psalm#10533 --- stubs/CoreGenericClasses.phpstub | 8 ++++++++ tests/ArrayAccessTest.php | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/stubs/CoreGenericClasses.phpstub b/stubs/CoreGenericClasses.phpstub index 542fec35875..93cb8cb42f0 100644 --- a/stubs/CoreGenericClasses.phpstub +++ b/stubs/CoreGenericClasses.phpstub @@ -82,6 +82,7 @@ interface ArrayAccess { * The return value will be casted to boolean if non-boolean was returned. * * @since 5.0.0 + * @no-named-arguments because of conflict with ArrayObject */ public function offsetExists($offset); @@ -94,6 +95,7 @@ interface ArrayAccess { * @psalm-ignore-nullable-return * * @since 5.0.0 + * @no-named-arguments because of conflict with ArrayObject */ public function offsetGet($offset); @@ -106,6 +108,7 @@ interface ArrayAccess { * @return void * * @since 5.0.0 + * @no-named-arguments because of conflict with ArrayObject */ public function offsetSet($offset, $value); @@ -117,6 +120,7 @@ interface ArrayAccess { * @return void * * @since 5.0.0 + * @no-named-arguments because of conflict with ArrayObject */ public function offsetUnset($offset); } @@ -162,6 +166,7 @@ class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Count * @return bool true if the requested index exists, otherwise false * * @since 5.0.0 + * @no-named-arguments because of conflict with ArrayAccess */ public function offsetExists($offset) { } @@ -173,6 +178,7 @@ class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Count * @return TValue The value at the specified index or false. * * @since 5.0.0 + * @no-named-arguments because of conflict with ArrayAccess */ public function offsetGet($offset) { } @@ -185,6 +191,7 @@ class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Count * @return void * * @since 5.0.0 + * @no-named-arguments because of conflict with ArrayAccess */ public function offsetSet($offset, $value) { } @@ -196,6 +203,7 @@ class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Count * @return void * * @since 5.0.0 + * @no-named-arguments because of conflict with ArrayAccess */ public function offsetUnset($offset) { } diff --git a/tests/ArrayAccessTest.php b/tests/ArrayAccessTest.php index 8481ac569e4..ba4b6ec7988 100644 --- a/tests/ArrayAccessTest.php +++ b/tests/ArrayAccessTest.php @@ -1233,6 +1233,25 @@ public function f(): void { 'assertions' => [], 'ignored_issues' => ['UndefinedDocblockClass'], ], + 'canExtendArrayObjectOffsetSet' => [ + 'code' => <<<'PHP' + */ + class C extends ArrayObject { + public function offsetSet(mixed $key, mixed $value): void { + parent::offsetSet($key, $value); + } + } + PHP, + 'assertions' => [], + 'ignored_issues' => [], + 'php_version' => '8.0', + ], ]; } @@ -1560,6 +1579,16 @@ function takesArrayOfFloats(array $arr): void { if ($x === null) {}', 'error_message' => 'PossiblyUndefinedArrayOffset', ], + 'cannotUseNamedArgumentsForArrayAccess' => [ + 'code' => <<<'PHP' + $a */ + function f(ArrayAccess $a): void { + echo $a->offsetGet(offset: 0); + } + PHP, + 'error_message' => 'NamedArgumentNotAllowed', + ], ]; } }