-
-
Notifications
You must be signed in to change notification settings - Fork 657
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix the view macro being unhygienic and not importing ElementChild #3162
base: main
Are you sure you want to change the base?
Conversation
While this approach would solve the hygiene problem for any code outside the view macro, anything inside would be exposed. To resolve this issue, you'd need to use fully qualified syntax for every trait method inside the macro. As an example, this function: pub fn simple_counter(initial_value: i32, step: i32) -> impl IntoView {
let (value, set_value) = signal(initial_value);
view! {
<div>
<span>"Value: " {value} "!"</span>
<button on:click=move |_| set_value.update(|value| *value += step)>"+1"</button>
</div>
}
} Which normally expands to: pub fn simple_counter(initial_value: i32, step: i32) -> impl IntoView {
let (value, set_value) = signal(initial_value);
{
#[allow(unused_braces)]
{
::leptos::prelude::View::new(
::leptos::tachys::html::element::div().child((
::leptos::tachys::html::element::span().child((
"Value: ",
::leptos::prelude::IntoRender::into_render({ value }),
"!",
)),
::leptos::tachys::html::element::button()
.child(
#[allow(unused_braces)]
{
"+1"
},
)
.on(::leptos::tachys::html::event::click, move |_| {
set_value.update(|value| *value += step)
}),
)),
)
}
}
} Would instead need to look like: pub fn simple_counter(initial_value: i32, step: i32) -> impl IntoView {
let (value, set_value) = signal(initial_value);
{
#[allow(unused_braces)]
{
::leptos::prelude::View::new(
<_ as ::leptos::prelude::ElementChild<_>>::child(
::leptos::tachys::html::element::div(),
(
<_ as ::leptos::prelude::ElementChild<_>>::child(
::leptos::tachys::html::element::span(),
(
"Value: ",
::leptos::prelude::IntoRender::into_render({ value }),
"!",
),
),
<_ as ::leptos::prelude::OnAttribute<_, _>>::on(
<_ as ::leptos::prelude::ElementChild<_>>::child(
::leptos::tachys::html::element::button(),
#[allow(unused_braces)]
{
"+1"
},
),
::leptos::tachys::html::event::click,
move |_| set_value.update(|value| *value += step),
),
),
)
)
}
}
} This is a little unfortunate for two reasons:
Personally, I think it would be very nice to have perfectly hygienic view macros. It won't come for free, though! |
A few observations:
Personally, I think the trade-off here (readability + token length of macro expansion vs. manual imports if you don't want to use a prelude) is currently well-balanced. If the two user stories are "I import the prelude and it just works" and "I don't import the prelude and the compiler tells me exactly what to manually import," I am pretty comfortable. But I am open to arguments against that. |
Regarding stuff that's explicitly used inside the macro, like If that's your decision, I'm fine with dropping the topic. |
Should fix #3161 .
Using the same code, the expansion now properly imports ElementChild.
A proper solution should probably import this only if necessary, but I have no idea how to do that, this is my first time actually working on proc macros.