Skip to content

Commit 02c7dd6

Browse files
committed
Merge remote-tracking branch 'upstream/master' into dom-bundle
2 parents 5010f34 + fc067ab commit 02c7dd6

12 files changed

Lines changed: 220 additions & 33 deletions

packages/yew-macro/src/hook/mod.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use proc_macro2::{Span, TokenStream};
22
use proc_macro_error::emit_error;
3-
use quote::quote;
3+
use quote::{quote, ToTokens};
44
use syn::parse::{Parse, ParseStream};
55
use syn::visit_mut;
6-
use syn::{parse_file, Ident, ItemFn, LitStr, ReturnType, Signature};
6+
use syn::{parse_file, GenericParam, Ident, ItemFn, LitStr, ReturnType, Signature};
77

88
mod body;
99
mod lifetime;
@@ -98,6 +98,19 @@ When used in function components and hooks, this hook is equivalent to:
9898
let output_type = &hook_sig.output_type;
9999

100100
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
101+
let call_generics = {
102+
let mut generics = generics.clone();
103+
104+
// We need to filter out lifetimes.
105+
generics.params = generics
106+
.params
107+
.into_iter()
108+
.filter(|m| !matches!(m, GenericParam::Lifetime(_)))
109+
.collect();
110+
111+
let (_impl_generics, ty_generics, _where_clause) = generics.split_for_impl();
112+
ty_generics.as_turbofish().to_token_stream()
113+
};
101114

102115
let ctx_ident = Ident::new("ctx", Span::mixed_site());
103116

@@ -120,13 +133,13 @@ When used in function components and hooks, this hook is equivalent to:
120133
let hook_lifetime_plus = quote! { #hook_lifetime + };
121134

122135
let boxed_inner_ident = Ident::new("boxed_inner", Span::mixed_site());
123-
let boxed_fn_type = quote! { ::std::boxed::Box<dyn #hook_lifetime_plus FnOnce(&mut ::yew::functional::HookContext) #inner_fn_rt> };
136+
let boxed_fn_type = quote! { ::std::boxed::Box<dyn #hook_lifetime_plus ::std::ops::FnOnce(&mut ::yew::functional::HookContext) #inner_fn_rt> };
124137

125138
// We need boxing implementation for `impl Trait` arguments.
126139
quote! {
127140
let #boxed_inner_ident = ::std::boxed::Box::new(
128141
move |#ctx_ident: &mut ::yew::functional::HookContext| #inner_fn_rt {
129-
#inner_fn_ident (#ctx_ident, #(#input_args,)*)
142+
#inner_fn_ident #call_generics (#ctx_ident, #(#input_args,)*)
130143
}
131144
) as #boxed_fn_type;
132145

@@ -138,8 +151,6 @@ When used in function components and hooks, this hook is equivalent to:
138151
let args_ident = Ident::new("args", Span::mixed_site());
139152
let hook_struct_name = Ident::new("HookProvider", Span::mixed_site());
140153

141-
let call_generics = ty_generics.as_turbofish();
142-
143154
let phantom_types = hook_sig.phantom_types();
144155
let phantom_lifetimes = hook_sig.phantom_lifetimes();
145156

@@ -155,7 +166,7 @@ When used in function components and hooks, this hook is equivalent to:
155166
fn run(mut self, #ctx_ident: &mut ::yew::functional::HookContext) -> Self::Output {
156167
let (#(#input_args,)*) = self.#args_ident;
157168

158-
#inner_fn_ident(#ctx_ident, #(#input_args,)*)
169+
#inner_fn_ident #call_generics (#ctx_ident, #(#input_args,)*)
159170
}
160171
}
161172

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use yew::prelude::*;
2+
3+
#[hook]
4+
fn use_reducer_default_action<T>() -> T::Action
5+
where
6+
T: Reducible + 'static,
7+
T::Action: Default + 'static,
8+
{
9+
T::Action::default()
10+
}
11+
12+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![no_implicit_prelude]
2+
3+
#[::yew::prelude::hook]
4+
fn use_a_const<const N: u32>() -> u32 {
5+
N
6+
}
7+
8+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// we need to re-test the macro hygiene here as it uses a different implementation for impl traits.
2+
#![no_implicit_prelude]
3+
4+
#[::yew::prelude::hook]
5+
fn use_some_string(a: impl ::std::convert::Into<::std::string::String>) -> ::std::string::String {
6+
a.into()
7+
}
8+
9+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use yew::prelude::*;
2+
3+
#[hook]
4+
fn use_as_is<'a>(input: &'a ()) -> &'a () {
5+
input
6+
}
7+
8+
fn main() {}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use yew::prelude::*;
2+
3+
#[derive(Debug, PartialEq, Clone)]
4+
struct Ctx;
5+
6+
#[hook]
7+
fn use_some_html() -> Html {
8+
if let Some(_m) = use_context::<Ctx>() {
9+
use_context::<Ctx>().unwrap();
10+
todo!()
11+
}
12+
13+
let _ = || {
14+
use_context::<Ctx>().unwrap();
15+
todo!()
16+
};
17+
18+
for _ in 0..10 {
19+
use_context::<Ctx>().unwrap();
20+
}
21+
22+
while let Some(_m) = use_context::<Ctx>() {
23+
use_context::<Ctx>().unwrap();
24+
}
25+
26+
match use_context::<Ctx>() {
27+
Some(_) => use_context::<Ctx>(),
28+
None => {
29+
todo!()
30+
}
31+
}
32+
33+
loop {
34+
use_context::<Ctx>().unwrap();
35+
todo!()
36+
}
37+
}
38+
39+
fn main() {}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
error: hooks cannot be called at this position.
2+
3+
= help: move hooks to the top-level of your function.
4+
= note: see: https://yew.rs/docs/next/concepts/function-components/introduction#hooks
5+
6+
--> tests/hook_attr/hook_location-fail.rs:9:9
7+
|
8+
9 | use_context::<Ctx>().unwrap();
9+
| ^^^^^^^^^^^
10+
11+
error: hooks cannot be called at this position.
12+
13+
= help: move hooks to the top-level of your function.
14+
= note: see: https://yew.rs/docs/next/concepts/function-components/introduction#hooks
15+
16+
--> tests/hook_attr/hook_location-fail.rs:14:9
17+
|
18+
14 | use_context::<Ctx>().unwrap();
19+
| ^^^^^^^^^^^
20+
21+
error: hooks cannot be called at this position.
22+
23+
= help: move hooks to the top-level of your function.
24+
= note: see: https://yew.rs/docs/next/concepts/function-components/introduction#hooks
25+
26+
--> tests/hook_attr/hook_location-fail.rs:19:9
27+
|
28+
19 | use_context::<Ctx>().unwrap();
29+
| ^^^^^^^^^^^
30+
31+
error: hooks cannot be called at this position.
32+
33+
= help: move hooks to the top-level of your function.
34+
= note: see: https://yew.rs/docs/next/concepts/function-components/introduction#hooks
35+
36+
--> tests/hook_attr/hook_location-fail.rs:22:26
37+
|
38+
22 | while let Some(_m) = use_context::<Ctx>() {
39+
| ^^^^^^^^^^^
40+
41+
error: hooks cannot be called at this position.
42+
43+
= help: move hooks to the top-level of your function.
44+
= note: see: https://yew.rs/docs/next/concepts/function-components/introduction#hooks
45+
46+
--> tests/hook_attr/hook_location-fail.rs:23:9
47+
|
48+
23 | use_context::<Ctx>().unwrap();
49+
| ^^^^^^^^^^^
50+
51+
error: hooks cannot be called at this position.
52+
53+
= help: move hooks to the top-level of your function.
54+
= note: see: https://yew.rs/docs/next/concepts/function-components/introduction#hooks
55+
56+
--> tests/hook_attr/hook_location-fail.rs:27:20
57+
|
58+
27 | Some(_) => use_context::<Ctx>(),
59+
| ^^^^^^^^^^^
60+
61+
error: hooks cannot be called at this position.
62+
63+
= help: move hooks to the top-level of your function.
64+
= note: see: https://yew.rs/docs/next/concepts/function-components/introduction#hooks
65+
66+
--> tests/hook_attr/hook_location-fail.rs:34:9
67+
|
68+
34 | use_context::<Ctx>().unwrap();
69+
| ^^^^^^^^^^^
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#![no_implicit_prelude]
2+
3+
#[derive(
4+
::std::prelude::rust_2021::Debug,
5+
::std::prelude::rust_2021::PartialEq,
6+
::std::prelude::rust_2021::Clone,
7+
)]
8+
struct Ctx;
9+
10+
#[::yew::prelude::hook]
11+
fn use_some_html() -> ::yew::prelude::Html {
12+
::yew::prelude::use_context::<Ctx>().unwrap();
13+
14+
if let ::std::prelude::rust_2021::Some(_m) = ::yew::prelude::use_context::<Ctx>() {
15+
::std::todo!()
16+
}
17+
18+
let _ctx = { ::yew::prelude::use_context::<Ctx>() };
19+
20+
match ::yew::prelude::use_context::<Ctx>() {
21+
::std::prelude::rust_2021::Some(_) => {
22+
::std::todo!()
23+
}
24+
::std::prelude::rust_2021::None => {
25+
::std::todo!()
26+
}
27+
}
28+
}
29+
30+
fn main() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#[allow(dead_code)]
2+
#[rustversion::attr(stable(1.56), test)]
3+
fn tests() {
4+
let t = trybuild::TestCases::new();
5+
t.pass("tests/hook_attr/*-pass.rs");
6+
t.compile_fail("tests/hook_attr/*-fail.rs");
7+
}

packages/yew/src/html/classes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl IntoPropValue<AttrValue> for Classes {
7676
None => unsafe { unreachable_unchecked() },
7777
}
7878
} else {
79-
AttrValue::Owned(self.to_string())
79+
AttrValue::Rc(Rc::from(self.to_string()))
8080
}
8181
}
8282
}

0 commit comments

Comments
 (0)