Skip to content

Commit

Permalink
Fix default Unit property on Component (#431)
Browse files Browse the repository at this point in the history
* Fix default unit Property on Component

Removes the adding of a default `()` unit property when none are
specified in the Component definition.

Fixes the above assumption in the `view` macro codegen.

* Remove Prop impl for Unit
  • Loading branch information
mc1098 authored Jun 8, 2022
1 parent 5f58fe3 commit 215a015
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 57 deletions.
2 changes: 1 addition & 1 deletion examples/hello-builder/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}
4 changes: 2 additions & 2 deletions examples/higher-order-components/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ fn MyComponent<G: Html>(cx: Scope, props: i32) -> View<G> {

fn higher_order_component<G: Html>(
Comp: &dyn Fn(Scope, i32) -> View<G>,
) -> impl Fn(Scope, ()) -> View<G> + '_ {
move |cx, _| {
) -> impl Fn(Scope) -> View<G> + '_ {
move |cx| {
view! { cx,
div {
Comp(42)
Expand Down
4 changes: 2 additions & 2 deletions examples/http-request-builder/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn App<G: Html>(cx: Scope) -> View<G> {
// crate).
SuspenseProps::builder()
.fallback(t("Loading"))
.children(Children::new(cx, |cx| VisitsCount(cx, ())))
.children(Children::new(cx, |cx| VisitsCount(cx)))
.build(),
))
.view(cx)
Expand All @@ -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));
}
15 changes: 0 additions & 15 deletions packages/sycamore-core/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
Expand Down
20 changes: 6 additions & 14 deletions packages/sycamore-macro/src/component/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
16 changes: 4 additions & 12 deletions packages/sycamore-macro/src/view/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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! {
Expand Down
42 changes: 32 additions & 10 deletions packages/sycamore-macro/tests/view/component-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,47 @@ error[E0425]: cannot find function, tuple struct or tuple variant `UnknownCompon
26 | let _: View<G> = 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<G> = 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<G: Html>(cx: Scope) -> View<G> {
| ^^^^^^^^^ -

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<G> = 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<G: Html>(cx: Scope, Prop { prop: _ }: Prop) -> View<G> {
| ^^^^^^^^^^^^^ ------------

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<G> = 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<G: Html>(cx: Scope, Prop { prop: _ }: Prop) -> View<G> {
| ^^^^^^^^^^^^^ ------------

error[E0308]: mismatched types
--> tests/view/component-fail.rs:33:60
Expand Down
2 changes: 1 addition & 1 deletion packages/sycamore/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ impl<'a, G: Html, F: FnOnce(Scope<'a>) -> G + 'a> ElementBuilder<'a, G, F> {
///
/// // Elsewhere...
/// # fn view<G: Html>(cx: Scope) -> View<G> {
/// component(|| MyComponent(cx, ()))
/// component(|| MyComponent(cx))
/// # }
/// ```
pub fn component<G>(f: impl FnOnce() -> View<G>) -> View<G>
Expand Down

0 comments on commit 215a015

Please sign in to comment.