Skip to content

fix: allow Option<T> and &T as VNode children in html! macro#4005

Merged
Madoshakalaka merged 3 commits into
masterfrom
fix/option-into-vnode
Feb 27, 2026
Merged

fix: allow Option<T> and &T as VNode children in html! macro#4005
Madoshakalaka merged 3 commits into
masterfrom
fix/option-into-vnode

Conversation

@Madoshakalaka
Copy link
Copy Markdown
Member

Description

Reported on Discord

Generalize IntoPropValue<VNode> for Option<VNode> into a blanket IntoPropValue<VNode> for Option<T> where T: IntoPropValue<VNode>.

The single-expression child path in the html! macro calls IntoPropValue::<VNode>::into_prop_value() directly, which only had an impl for Option<VNode>. This is a regression from the removal of the ToHtml trait, which had a blanket Option<T: ToHtml> impl.

Checklist

  • I have reviewed my own code
  • I have added tests

github-actions[bot]
github-actions Bot previously approved these changes Feb 26, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 26, 2026

Visit the preview URL for this PR (updated for commit cdb6993):

https://yew-rs--pr4005-fix-option-into-vnod-3dj9h7i0.web.app

(expires Thu, 05 Mar 2026 07:28:01 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 26, 2026

Benchmark - core

Yew Master

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.795 ns      │ 3.101 ns      │ 2.798 ns      │ 2.803 ns      │ 100     │ 1000000000

Pull Request

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.774 ns      │ 4.036 ns      │ 2.78 ns       │ 2.977 ns      │ 100     │ 1000000000

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 26, 2026

Benchmark - SSR

Yew Master

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 290.936 291.245 291.128 0.096
Hello World 10 476.046 501.122 484.473 10.112
Function Router 10 1646.666 1695.144 1665.246 14.554
Concurrent Task 10 1004.417 1006.852 1005.880 0.817
Many Providers 10 1083.012 1134.020 1104.868 14.942

Pull Request

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 290.992 292.455 291.291 0.424
Hello World 10 463.661 468.665 464.809 1.790
Function Router 10 1666.271 1695.457 1681.182 9.304
Concurrent Task 10 1004.373 1006.585 1005.648 0.839
Many Providers 10 1089.927 1124.513 1110.961 12.754

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 26, 2026

Size Comparison

Details
examples master (KB) pull request (KB) diff (KB) diff (%)
async_clock 96.823 96.823 0 0.000%
boids 165.482 165.482 0 0.000%
communication_child_to_parent 89.899 89.899 0 0.000%
communication_grandchild_with_grandparent 100.772 100.772 0 0.000%
communication_grandparent_to_grandchild 97.273 97.273 0 0.000%
communication_parent_to_child 87.314 87.314 0 0.000%
contexts 103.035 103.035 0 0.000%
counter 84.037 84.037 0 0.000%
counter_functional 85.410 85.410 0 0.000%
dyn_create_destroy_apps 87.122 87.122 0 0.000%
file_upload 96.566 96.566 0 0.000%
function_delayed_input 90.901 90.901 0 0.000%
function_memory_game 168.782 168.782 0 0.000%
function_router 326.337 326.337 0 0.000%
function_todomvc 160.736 160.736 0 0.000%
futures 232.128 232.128 0 0.000%
game_of_life 102.119 102.119 0 0.000%
immutable 244.170 244.170 0 0.000%
inner_html 78.616 78.616 0 0.000%
js_callback 107.492 107.492 0 0.000%
keyed_list 177.171 177.171 0 0.000%
mount_point 81.754 81.754 0 0.000%
nested_list 110.428 110.428 0 0.000%
node_refs 89.300 89.300 0 0.000%
password_strength 1725.986 1725.986 0 0.000%
portals 90.777 90.777 0 0.000%
router 296.723 296.723 0 0.000%
suspense 110.946 110.946 0 0.000%
timer 86.637 86.637 0 0.000%
timer_functional 96.147 96.147 0 0.000%
todomvc 139.338 139.338 0 0.000%
two_apps 83.903 83.903 0 0.000%
web_worker_fib 133.659 133.659 0 0.000%
web_worker_prime 184.450 184.450 0 0.000%
webgl 81.250 81.250 0 0.000%

✅ None of the examples has changed their size significantly.

…html!

Generalize `IntoPropValue<VNode> for Option<VNode>` into a blanket
`IntoPropValue<VNode> for Option<T>` where `T: IntoPropValue<VNode>`.

The single-expression child path in the html! macro calls
`IntoPropValue::<VNode>::into_prop_value()` directly, which only had
an impl for `Option<VNode>`. This is a regression from the removal of
the `ToHtml` trait, which had a blanket `Option<T: ToHtml>` impl.
github-actions[bot]
github-actions Bot previously approved these changes Feb 26, 2026
@Madoshakalaka Madoshakalaka changed the title fix: allow Option<String> and Option<AttrValue> as VNode children fix: allow Option<T> and &T as VNode children in html! macro Feb 26, 2026
github-actions[bot]
github-actions Bot previously approved these changes Feb 26, 2026
@Madoshakalaka
Copy link
Copy Markdown
Member Author

Also adds IntoPropValue<VNode> impls for &T references. The same ToHtml removal that broke Option<T> also broke references as single children, e.g. {element} where element: &i32 from .iter() required a manual * deref in 0.22 but not in 0.21.

Discovered via yew-hooks, which had to add * derefs in several doc examples to adapt to 0.22: yewstack/yew-hooks@0b39e74

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.
github-actions[bot]
github-actions Bot previously approved these changes Feb 26, 2026
@Madoshakalaka Madoshakalaka added A-yew Area: The main yew crate A-yew-macro Area: The yew-macro crate labels Feb 26, 2026
@Madoshakalaka Madoshakalaka merged commit 0fde6cf into master Feb 27, 2026
26 checks passed
@Madoshakalaka Madoshakalaka deleted the fix/option-into-vnode branch February 27, 2026 04:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-yew Area: The main yew crate A-yew-macro Area: The yew-macro crate bug ergonomics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant