Improve actions macros (#3292)

Mikayla Maki created

- `actions!` now uses `#[action]` on each struct to reduce duplication.
- The `#[action]` macro now works on unit structs.
- Renamed `menu::unused` to `menu::init` and added more explanation in
comments.

Release Notes:

- N/A

Change summary

crates/gpui2/src/action.rs        |  3 +--
crates/gpui2_macros/src/action.rs | 20 ++++++++++++++------
crates/menu2/src/menu2.rs         |  8 ++++++--
crates/zed2/src/main.rs           |  5 +----
4 files changed, 22 insertions(+), 14 deletions(-)

Detailed changes

crates/gpui2/src/action.rs 🔗

@@ -176,8 +176,7 @@ macro_rules! actions {
     () => {};
 
     ( $name:ident ) => {
-        #[gpui::register_action]
-        #[derive(::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug, ::std::cmp::PartialEq, $crate::serde::Deserialize)]
+        #[gpui::action]
         pub struct $name;
     };
 

crates/gpui2_macros/src/action.rs 🔗

@@ -34,13 +34,21 @@ pub fn action(_attr: TokenStream, item: TokenStream) -> TokenStream {
     let visibility = input.vis;
 
     let output = match input.data {
-        syn::Data::Struct(ref struct_data) => {
-            let fields = &struct_data.fields;
-            quote! {
-                #attributes
-                #visibility struct #name #fields
+        syn::Data::Struct(ref struct_data) => match &struct_data.fields {
+            syn::Fields::Named(_) | syn::Fields::Unnamed(_) => {
+                let fields = &struct_data.fields;
+                quote! {
+                    #attributes
+                    #visibility struct #name #fields
+                }
             }
-        }
+            syn::Fields::Unit => {
+                quote! {
+                    #attributes
+                    #visibility struct #name;
+                }
+            }
+        },
         syn::Data::Enum(ref enum_data) => {
             let variants = &enum_data.variants;
             quote! {

crates/menu2/src/menu2.rs 🔗

@@ -1,9 +1,13 @@
 use gpui::actions;
 
-// todo!(remove this)
+// If the zed binary doesn't use anything in this crate, it will be optimized away
+// and the actions won't initialize. So we just provide an empty initialization function
+// to be called from main.
+//
+// These may provide relevant context:
 // https://github.com/rust-lang/rust/issues/47384
 // https://github.com/mmastrac/rust-ctor/issues/280
-pub fn unused() {}
+pub fn init() {}
 
 actions!(
     Cancel,

crates/zed2/src/main.rs 🔗

@@ -57,10 +57,7 @@ use zed2::{
 mod open_listener;
 
 fn main() {
-    //TODO!(figure out what the linker issues are here)
-    // https://github.com/rust-lang/rust/issues/47384
-    // https://github.com/mmastrac/rust-ctor/issues/280
-    menu::unused();
+    menu::init();
     let http = http::client();
     init_paths();
     init_logger();