Skip to content

Commit 6331a01

Browse files
committed
fix: allow &T references as VNode children in html! macro
Add IntoPropValue<VNode> impls for &T where T already has an impl, via the impl_into_prop_value_via_display! and impl_into_prop_value_via_attr_value! macros. This fixes a regression from the ToHtml removal where expressions like {&num} or {element} (where element: &i32 from .iter()) failed as single children of HTML elements.
1 parent 2b996c2 commit 6331a01

4 files changed

Lines changed: 51 additions & 23 deletions

File tree

packages/yew-macro/tests/html_macro/component-fail.stderr

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -488,14 +488,14 @@ error[E0277]: the trait bound `{integer}: IntoPropValue<String>` is not satisfie
488488
| required by a bound introduced by this call
489489
|
490490
= help: the following other types implement trait `IntoPropValue<T>`:
491-
f32
492-
f64
493-
i128
494-
i16
495-
i32
496-
i64
497-
i8
498-
isize
491+
&f32
492+
&f64
493+
&i128
494+
&i16
495+
&i32
496+
&i64
497+
&i8
498+
&isize
499499
and $N others
500500
note: required by a bound in `ChildPropertiesBuilder::string`
501501
--> tests/html_macro/component-fail.rs:4:17
@@ -516,14 +516,14 @@ error[E0277]: the trait bound `{integer}: IntoPropValue<String>` is not satisfie
516516
| required by a bound introduced by this call
517517
|
518518
= help: the following other types implement trait `IntoPropValue<T>`:
519-
f32
520-
f64
521-
i128
522-
i16
523-
i32
524-
i64
525-
i8
526-
isize
519+
&f32
520+
&f64
521+
&i128
522+
&i16
523+
&i32
524+
&i64
525+
&i8
526+
&isize
527527
and $N others
528528
note: required by a bound in `ChildPropertiesBuilder::string`
529529
--> tests/html_macro/component-fail.rs:4:17
@@ -560,9 +560,9 @@ error[E0277]: the trait bound `u32: IntoPropValue<i32>` is not satisfied
560560
| |
561561
| required by a bound introduced by this call
562562
|
563-
= help: the trait `IntoPropValue<i32>` is not implemented for `u32`
564-
but trait `IntoPropValue<VNode>` is implemented for it
565-
= help: for that trait implementation, expected `VNode`, found `i32`
563+
= help: the following other types implement trait `IntoPropValue<T>`:
564+
&u32
565+
u32
566566
note: required by a bound in `ChildPropertiesBuilder::int`
567567
--> tests/html_macro/component-fail.rs:4:17
568568
|

packages/yew-macro/tests/html_macro/element-fail.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -465,14 +465,14 @@ error[E0277]: the trait bound `NotToString: IntoPropValue<Option<implicit_clone:
465465
| ^^^^^^^^^^^ the trait `IntoPropValue<Option<implicit_clone::unsync::string::IString>>` is not implemented for `NotToString`
466466
|
467467
= help: the following other types implement trait `IntoPropValue<T>`:
468+
`&&String` implements `IntoPropValue<VNode>`
469+
`&&str` implements `IntoPropValue<VNode>`
468470
`&'static [(K, V)]` implements `IntoPropValue<implicit_clone::unsync::map::IMap<K, V>>`
469471
`&'static [T]` implements `IntoPropValue<implicit_clone::unsync::array::IArray<T>>`
470472
`&'static str` implements `IntoPropValue<Classes>`
471473
`&'static str` implements `IntoPropValue<Option<String>>`
472474
`&'static str` implements `IntoPropValue<Option<implicit_clone::unsync::string::IString>>`
473475
`&'static str` implements `IntoPropValue<String>`
474-
`&'static str` implements `IntoPropValue<implicit_clone::unsync::string::IString>`
475-
`&ChildrenRenderer<VNode>` implements `IntoPropValue<VNode>`
476476
and $N others
477477

478478
error[E0277]: the trait bound `Option<NotToString>: IntoPropValue<Option<implicit_clone::unsync::string::IString>>` is not satisfied
@@ -665,14 +665,14 @@ error[E0277]: the trait bound `NotToString: IntoPropValue<Option<implicit_clone:
665665
| ^^^^^^^^^^^ the trait `IntoPropValue<Option<implicit_clone::unsync::string::IString>>` is not implemented for `NotToString`
666666
|
667667
= help: the following other types implement trait `IntoPropValue<T>`:
668+
`&&String` implements `IntoPropValue<VNode>`
669+
`&&str` implements `IntoPropValue<VNode>`
668670
`&'static [(K, V)]` implements `IntoPropValue<implicit_clone::unsync::map::IMap<K, V>>`
669671
`&'static [T]` implements `IntoPropValue<implicit_clone::unsync::array::IArray<T>>`
670672
`&'static str` implements `IntoPropValue<Classes>`
671673
`&'static str` implements `IntoPropValue<Option<String>>`
672674
`&'static str` implements `IntoPropValue<Option<implicit_clone::unsync::string::IString>>`
673675
`&'static str` implements `IntoPropValue<String>`
674-
`&'static str` implements `IntoPropValue<implicit_clone::unsync::string::IString>`
675-
`&ChildrenRenderer<VNode>` implements `IntoPropValue<VNode>`
676676
and $N others
677677

678678
error[E0277]: the trait bound `(): IntoPropValue<yew::NodeRef>` is not satisfied

packages/yew-macro/tests/html_macro/html-element-pass.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,15 @@ fn compile_pass() {
134134

135135
let opt_none: ::std::option::Option<::std::string::String> = ::std::option::Option::None;
136136
_ = ::yew::html! { <div>{opt_none}</div> };
137+
138+
let num = 42i32;
139+
_ = ::yew::html! { <div>{&num}</div> };
140+
141+
let text = ::std::string::String::new();
142+
_ = ::yew::html! { <div>{&text}</div> };
143+
144+
let sr: &::core::primitive::str = "hello";
145+
_ = ::yew::html! { <div>{&sr}</div> };
137146
}
138147

139148
fn main() {}

packages/yew/src/html/conversion/into_prop_value.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,12 @@ macro_rules! impl_into_prop_value_via_display {
292292
VText::from(self).into()
293293
}
294294
}
295+
impl IntoPropValue<VNode> for &$from_ty {
296+
#[inline(always)]
297+
fn into_prop_value(self) -> VNode {
298+
self.clone().into_prop_value()
299+
}
300+
}
295301
};
296302
}
297303

@@ -362,6 +368,19 @@ mod test {
362368
let _: VNode = Some(true).into_prop_value();
363369
}
364370

371+
#[test]
372+
fn test_ref_to_vnode() {
373+
let _: VNode = (&42i32).into_prop_value();
374+
let _: VNode = (&true).into_prop_value();
375+
let _: VNode = (&1.5f64).into_prop_value();
376+
let s = String::from("hello");
377+
let _: VNode = (&s).into_prop_value();
378+
let a = AttrValue::Static("hello");
379+
let _: VNode = (&a).into_prop_value();
380+
let sr: &str = "hello";
381+
let _: VNode = (&sr).into_prop_value();
382+
}
383+
365384
#[test]
366385
fn test_callback() {
367386
let _: Callback<String> = (|_: String| ()).into_prop_value();

0 commit comments

Comments
 (0)