Add a compile test for the element derive (#2840)

Mikayla Maki created

Tried to use this the new element derive on a branch and ran into some
bugs, this fixes those.

Release Notes:

- N/A

Change summary

Cargo.lock                            |  1 +
crates/gpui/src/elements.rs           |  4 ++++
crates/gpui_macros/Cargo.toml         |  2 ++
crates/gpui_macros/src/gpui_macros.rs |  8 ++++++--
crates/gpui_macros/tests/test.rs      | 14 ++++++++++++++
5 files changed, 27 insertions(+), 2 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -3172,6 +3172,7 @@ dependencies = [
 name = "gpui_macros"
 version = "0.1.0"
 dependencies = [
+ "gpui",
  "proc-macro2",
  "quote",
  "syn 1.0.109",

crates/gpui/src/elements.rs 🔗

@@ -201,6 +201,10 @@ pub trait Element<V: View>: 'static {
     }
 }
 
+pub trait RenderElement {
+    fn render<V: View>(&mut self, view: &mut V, cx: &mut ViewContext<V>) -> AnyElement<V>;
+}
+
 trait AnyElementState<V: View> {
     fn layout(
         &mut self,

crates/gpui_macros/src/gpui_macros.rs 🔗

@@ -283,8 +283,12 @@ pub fn element_derive(input: TokenStream) -> TokenStream {
 
     // The name of the struct/enum
     let name = input.ident;
+    let must_implement = format_ident!("{}MustImplementRenderElement", name);
 
     let expanded = quote! {
+        trait #must_implement : gpui::elements::RenderElement {}
+        impl #must_implement for #name {}
+
         impl<V: gpui::View> gpui::elements::Element<V> for #name {
             type LayoutState = gpui::elements::AnyElement<V>;
             type PaintState = ();
@@ -307,7 +311,7 @@ pub fn element_derive(input: TokenStream) -> TokenStream {
                 visible_bounds: gpui::geometry::rect::RectF,
                 element: &mut gpui::elements::AnyElement<V>,
                 view: &mut V,
-                cx: &mut gpui::ViewContext<V>,
+                cx: &mut gpui::PaintContext<V>,
             ) {
                 element.paint(scene, bounds.origin(), visible_bounds, view, cx);
             }
@@ -332,7 +336,7 @@ pub fn element_derive(input: TokenStream) -> TokenStream {
                 _: &(),
                 view: &V,
                 cx: &gpui::ViewContext<V>,
-            ) -> serde_json::Value {
+            ) -> gpui::serde_json::Value {
                 element.debug(view, cx)
             }
         }

crates/gpui_macros/tests/test.rs 🔗

@@ -0,0 +1,14 @@
+use gpui::{elements::RenderElement, View, ViewContext};
+use gpui_macros::Element;
+
+#[test]
+fn test_derive_render_element() {
+    #[derive(Element)]
+    struct TestElement {}
+
+    impl RenderElement for TestElement {
+        fn render<V: View>(&mut self, _: &mut V, _: &mut ViewContext<V>) -> gpui::AnyElement<V> {
+            unimplemented!()
+        }
+    }
+}