diff --git a/examples/hello-builder/src/main.rs b/examples/hello-builder/src/main.rs index 771ac8397..43fa9f750 100644 --- a/examples/hello-builder/src/main.rs +++ b/examples/hello-builder/src/main.rs @@ -26,5 +26,5 @@ fn main() { console_error_panic_hook::set_once(); console_log::init_with_level(log::Level::Debug).unwrap(); - sycamore::render(|cx| component(|| App(cx, ()))); + sycamore::render(|cx| component(|| App(cx))); } diff --git a/examples/higher-order-components/src/main.rs b/examples/higher-order-components/src/main.rs index afd3e93e8..57a135c70 100644 --- a/examples/higher-order-components/src/main.rs +++ b/examples/higher-order-components/src/main.rs @@ -11,8 +11,8 @@ fn MyComponent(cx: Scope, props: i32) -> View { fn higher_order_component( Comp: &dyn Fn(Scope, i32) -> View, -) -> impl Fn(Scope, ()) -> View + '_ { - move |cx, _| { +) -> impl Fn(Scope) -> View + '_ { + move |cx| { view! { cx, div { Comp(42) diff --git a/examples/http-request-builder/src/main.rs b/examples/http-request-builder/src/main.rs index d482a53c9..a3c2b9475 100644 --- a/examples/http-request-builder/src/main.rs +++ b/examples/http-request-builder/src/main.rs @@ -41,7 +41,7 @@ fn App(cx: Scope) -> View { // crate). SuspenseProps::builder() .fallback(t("Loading")) - .children(Children::new(cx, |cx| VisitsCount(cx, ()))) + .children(Children::new(cx, |cx| VisitsCount(cx))) .build(), )) .view(cx) @@ -51,5 +51,5 @@ fn main() { console_error_panic_hook::set_once(); console_log::init_with_level(log::Level::Debug).unwrap(); - sycamore::render(|cx| App(cx, ())); + sycamore::render(|cx| App(cx)); } diff --git a/packages/sycamore-core/src/component.rs b/packages/sycamore-core/src/component.rs index d834bb8b3..f3eeaf7cb 100644 --- a/packages/sycamore-core/src/component.rs +++ b/packages/sycamore-core/src/component.rs @@ -31,21 +31,6 @@ pub trait Prop { fn builder() -> Self::Builder; } -/* Implement Prop for () */ - -/// A builder for `()`. -#[doc(hidden)] -pub struct UnitBuilder; -impl UnitBuilder { - pub fn build(self) {} -} -impl Prop for () { - type Builder = UnitBuilder; - fn builder() -> Self::Builder { - UnitBuilder - } -} - /// Get the builder for the component function. #[doc(hidden)] pub fn element_like_component_builder<'a, T: Prop + 'a, G: GenericNode>( diff --git a/packages/sycamore-macro/src/component/mod.rs b/packages/sycamore-macro/src/component/mod.rs index 530103562..2707457eb 100644 --- a/packages/sycamore-macro/src/component/mod.rs +++ b/packages/sycamore-macro/src/component/mod.rs @@ -89,11 +89,6 @@ impl Parse for ComponentFunction { } } - // If only 1 argument, add an additional argument of type `()`. - if inputs.len() == 1 { - sig.inputs.push(parse_quote! { _: () }); - } - Ok(Self { f }) } item => Err(syn::Error::new_spanned( @@ -142,15 +137,10 @@ fn async_comp_inputs_from_sig_inputs( unreachable!("We check in parsing that the first argument is not a receiver"); }; - // In parsing we checked that there were two args so we can unwrap here. - let prop_fn_arg = inputs.next().unwrap(); - let prop_arg = match prop_fn_arg { + let prop_arg = inputs.next(); + let prop_arg = prop_arg.map(|prop_fn_arg| match prop_fn_arg { FnArg::Typed(t) => match &*t.pat { Pat::Ident(id) => pat_ident_arm(&mut sync_input, prop_fn_arg, id), - Pat::Wild(_) => { - sync_input.push(prop_fn_arg.clone()); - parse_quote!(()) - } Pat::Struct(pat_struct) => { // For the sync input we don't want a destructured pattern but just to take a // `syn::PatType` (i.e. `props: MyPropStruct`) then the inner async function @@ -182,9 +172,11 @@ fn async_comp_inputs_from_sig_inputs( _ => panic!("unexpected pattern!"), }, FnArg::Receiver(_) => unreachable!(), - }; + }); - async_args.push(prop_arg); + if let Some(arg) = prop_arg { + async_args.push(arg); + } AsyncCompInputs { cx, diff --git a/packages/sycamore-macro/src/view/codegen.rs b/packages/sycamore-macro/src/view/codegen.rs index 544fc5b25..cbe1880f1 100644 --- a/packages/sycamore-macro/src/view/codegen.rs +++ b/packages/sycamore-macro/src/view/codegen.rs @@ -4,7 +4,7 @@ //! of some internal state during the entire codegen. use proc_macro2::TokenStream; -use quote::{quote, quote_spanned}; +use quote::quote; use syn::spanned::Spanned; use syn::{Expr, ExprLit, Ident, Lit}; @@ -447,26 +447,18 @@ impl Codegen { match comp { Component::FnLike(comp) => { let FnLikeComponent { ident, args } = comp; - if args.empty_or_trailing() { - quote! { ::sycamore::component::component_scope(move || #ident(#cx, ())) } - } else { - quote! { ::sycamore::component::component_scope(move || #ident(#cx, #args)) } - } + quote! { ::sycamore::component::component_scope(move || #ident(#cx, #args)) } } Component::ElementLike(comp) => { let ElementLikeComponent { ident, - brace, props, children, + .. } = comp; if props.is_empty() && children.is_none() { - // If no props, just generate a `()` for props. - // We make sure to give the `()` the same span as the brace tokens for proper - // error spans. - let unit = quote_spanned! { brace.span=> () }; quote! { - ::sycamore::component::component_scope(move || #ident(#cx, #unit)) + ::sycamore::component::component_scope(move || #ident(#cx)) } } else { let mut props_quoted = quote! { diff --git a/packages/sycamore-macro/tests/view/component-fail.stderr b/packages/sycamore-macro/tests/view/component-fail.stderr index 03f7bae63..7169835d8 100644 --- a/packages/sycamore-macro/tests/view/component-fail.stderr +++ b/packages/sycamore-macro/tests/view/component-fail.stderr @@ -18,25 +18,47 @@ error[E0425]: cannot find function, tuple struct or tuple variant `UnknownCompon 26 | let _: View = view! { cx, UnknownComponent {} }; | ^^^^^^^^^^^^^^^^ not found in this scope -error[E0308]: mismatched types - --> tests/view/component-fail.rs:29:48 +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> tests/view/component-fail.rs:29:38 | 29 | let _: View = view! { cx, Component(1) }; - | ^ expected `()`, found integer + | -- ^^^^^^^^^ - supplied 2 arguments + | | + | expected 1 argument + | +note: function defined here + --> tests/view/component-fail.rs:17:4 + | +17 | fn Component(cx: Scope) -> View { + | ^^^^^^^^^ - -error[E0308]: mismatched types - --> tests/view/component-fail.rs:31:26 +error[E0061]: this function takes 2 arguments but 1 argument was supplied + --> tests/view/component-fail.rs:31:38 | 31 | let _: View = view! { cx, PropComponent() }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Prop`, found `()` + | -- ^^^^^^^^^^^^^ expected 2 arguments + | | + | supplied 1 argument | - = note: this error originates in the macro `view` (in Nightly builds, run with -Z macro-backtrace for more info) +note: function defined here + --> tests/view/component-fail.rs:9:8 + | +9 | pub fn PropComponent(cx: Scope, Prop { prop: _ }: Prop) -> View { + | ^^^^^^^^^^^^^ ------------ -error[E0308]: mismatched types - --> tests/view/component-fail.rs:32:52 +error[E0061]: this function takes 2 arguments but 1 argument was supplied + --> tests/view/component-fail.rs:32:38 | 32 | let _: View = view! { cx, PropComponent {} }; - | ^^ expected struct `Prop`, found `()` + | -- ^^^^^^^^^^^^^ expected 2 arguments + | | + | supplied 1 argument + | +note: function defined here + --> tests/view/component-fail.rs:9:8 + | +9 | pub fn PropComponent(cx: Scope, Prop { prop: _ }: Prop) -> View { + | ^^^^^^^^^^^^^ ------------ error[E0308]: mismatched types --> tests/view/component-fail.rs:33:60 diff --git a/packages/sycamore/src/builder.rs b/packages/sycamore/src/builder.rs index 6c9e36c95..c3e58cfc4 100644 --- a/packages/sycamore/src/builder.rs +++ b/packages/sycamore/src/builder.rs @@ -715,7 +715,7 @@ impl<'a, G: Html, F: FnOnce(Scope<'a>) -> G + 'a> ElementBuilder<'a, G, F> { /// /// // Elsewhere... /// # fn view(cx: Scope) -> View { -/// component(|| MyComponent(cx, ())) +/// component(|| MyComponent(cx)) /// # } /// ``` pub fn component(f: impl FnOnce() -> View) -> View