Skip to content

Commit 53eeb0b

Browse files
Treat some references differently for ergonomics (#13)
Discovered by @Madoshakalaka If a reference type is actually intended, `#[autoprops]` will currently ignore that and put a referenceless type into the props struct. For example: ```rust #[autoprops] #[component] pub fn Test(string: &'static str) { html!{} } ``` In this case `'static` is ignored, and `str` is attempted to be put into props struct. As a workaround, currently works: ```rust #[autoprops] #[component] pub fn Test(string: &&'static str) { html!{} } ``` But it is unergonomic. It is well known that reference is wanted (by the lifetime specifier existing), so let's put such references into props struct as-is.
1 parent 018b8be commit 53eeb0b

5 files changed

Lines changed: 20 additions & 6 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
output.log
33
.envrc
44
.aider*
5+
.vscode

src/autoprops.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,10 @@ impl Autoprops {
119119
.iter()
120120
.filter_map(|arg| match arg {
121121
syn::FnArg::Typed(syn::PatType { pat, ty, .. })
122-
if !matches!(**ty, syn::Type::Reference(_)) =>
122+
if !matches!(
123+
**ty,
124+
syn::Type::Reference(syn::TypeReference { lifetime: None, .. })
125+
) =>
123126
{
124127
Some(quote! {
125128
let #pat = ::yew::html::ImplicitClone::implicit_clone(#pat);
@@ -154,9 +157,11 @@ impl Autoprops {
154157
.iter()
155158
.filter_map(|arg| match arg {
156159
syn::FnArg::Typed(syn::PatType { attrs, pat, ty, .. }) => match ty.as_ref() {
157-
syn::Type::Reference(syn::TypeReference { elem, .. }) => {
158-
Some(quote! { #(#attrs)* #vis #pat: #elem, })
159-
}
160+
syn::Type::Reference(syn::TypeReference {
161+
elem,
162+
lifetime: None,
163+
..
164+
}) => Some(quote! { #(#attrs)* #vis #pat: #elem, }),
160165
_ => Some(quote! { #(#attrs)* #vis #pat: #ty, }),
161166
},
162167
_ => None,

src/function_component.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// copy-pasted from yew-macro because proc-macro crates cannot export any items
2+
// TODO separate yew's macros into their own library common for yew-macro and yew-autoprops
23

34
use syn::parse::{Parse, ParseStream};
45
use syn::Ident;

src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,5 @@ pub fn autoprops(
1111
let mut autoprops = syn::parse_macro_input!(item as autoprops::Autoprops);
1212
let args = syn::parse_macro_input!(attr as autoprops::AutopropsArgs);
1313
autoprops.apply_args(args);
14-
15-
proc_macro::TokenStream::from(autoprops.into_token_stream())
14+
autoprops.into_token_stream().into()
1615
}

tests/function_component_attr/autoprops-pass.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ where
103103
}
104104
}
105105

106+
#[::yew_autoprops::autoprops]
107+
#[::yew::component]
108+
fn CompWithIntendedRef(s: &'static ::std::primitive::str) -> ::yew::Html {
109+
let _ = s;
110+
::yew::html! {}
111+
}
112+
106113
fn compile_pass() {
107114
let _ = ::yew::html! { <CompUseFnName /> };
108115
let _ = ::yew::html! { <CompNoProperties /> };
@@ -115,6 +122,7 @@ fn compile_pass() {
115122
let _ = ::yew::html! { <CompHtmlResult /> };
116123
let _ = ::yew::html! { <CompWithDefaultGeneric /> };
117124
let _ = ::yew::html! { <CompWithDefaultGeneric<::std::primitive::u32> /> };
125+
let _ = ::yew::html! { <CompWithIntendedRef s="foo" /> };
118126
}
119127

120128
fn main() {}

0 commit comments

Comments
 (0)