[php-src] Issue #8421: Attributes that target functions are not valid for anonymous functions defined within a method

From: Date: Thu, 21 Apr 2022 17:12:06 +0000
Subject: [php-src] Issue #8421: Attributes that target functions are not valid for anonymous functions defined within a method
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-241135@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/8421 Author: ollieread ### Description If an anonymous function is defined inside a method, attempting to create a new instance of any attribute attached to it that only targets functions (#[Attribute(Attribute::TARGET_FUNCTION)]) will cause an error with the message. ``` Fatal error: Uncaught Error: Attribute "AttributeName" cannot target method (allowed targets: function) ``` This happens in both object and static contexts. Changing the attribute to work with methods instead will cause an inverted error if the closure is defined outside of a method within the global context. ## Examples This code works fine and gives no output, as expected. (https://3v4l.org/iDuIL#v8.1.4) ```php <?php #[Attribute(Attribute::TARGET_FUNCTION)] class FunctionAttribute { } $closure = #[FunctionAttribute] fn() => true; class Something { public function get(Closure $closure) { return (new ReflectionFunction($closure)) ->getAttributes(FunctionAttribute::class)[0] ->newInstance(); } } (new Something)->get($closure); ``` This code works fine and gives no output, as expected. (https://3v4l.org/iDuIL#v8.1.4) ```php <?php #[Attribute(Attribute::TARGET_FUNCTION)] class FunctionAttribute { } $closure = #[FunctionAttribute] fn() => true; class Something { public function get(Closure $closure) { return (new ReflectionFunction($closure)) ->getAttributes(FunctionAttribute::class)[0] ->newInstance(); } } (new Something)->get($closure); ``` This code gives an error. (https://3v4l.org/Clenb#v8.1.4) ```php <?php #[Attribute(Attribute::TARGET_FUNCTION)] class FunctionAttribute { } class Something { public function get() { $closure = #[FunctionAttribute] fn() => true; return (new ReflectionFunction($closure)) ->getAttributes(FunctionAttribute::class)[0] ->newInstance(); } } (new Something)->get(); ``` Its output is: ``` Fatal error: Uncaught Error: Attribute "FunctionAttribute" cannot target method (allowed targets: function) in /in/Clenb:16 Stack trace: #0 /in/Clenb(16): ReflectionAttribute->newInstance() #1 /in/Clenb(20): Something->get() #2 {main} thrown in /in/Clenb on line 16 Process exited with code 255. ``` As does this same code, but using a static method instead. (https://3v4l.org/s4Gk0#v8.1.4) ```php <?php #[Attribute(Attribute::TARGET_FUNCTION)] class FunctionAttribute { } class Something { public static function get() { $closure = #[FunctionAttribute] fn() => true; return (new ReflectionFunction($closure)) ->getAttributes(FunctionAttribute::class)[0] ->newInstance(); } } Something::get(); ``` Which also outputs: ``` Fatal error: Uncaught Error: Attribute "FunctionAttribute" cannot target method (allowed targets: function) in /in/s4Gk0:16 Stack trace: #0 /in/s4Gk0(16): ReflectionAttribute->newInstance() #1 /in/s4Gk0(20): Something::get() #2 {main} thrown in /in/s4Gk0 on line 16 Process exited with code 255. ``` ### PHP Version 8.1.4 ### Operating System _No response_

« previous php.bugs (#241135) next »