How to "erase" generic type in function arguments
⚓ Rust 📅 2025-10-16 👤 surdeus 👁️ 8The origin of this question is me playing with Leptos and (as always :/) being screamed at by the compiler at the third line of code. While there is probably a Leptos-specific way of solving my problem I'd like to understand what options do I have in a more generic context.
I have a function that takes an optional closure Option<F> and I need to call it passing None as the argument. Obviously the compiler wants to know the type of F and with a simple F I can just pass the correct type. But in Leptos components, my types are a bit more complex (enough that specifing the type is not trivial, at least for me) and it is possible to call a component without the argument and have it replaced by the default (i.e., None), a feature that makes component instantiation very ergonomic except that it does not work if generics are involved.
I was thinking about using some kind of wrapper type or trait that does not expose the generic F and let me pass just None instead of None::<T> but I havent found a solution yet. Does anybody knows how to do that?
Full code:
fn take_optional_f<F>(f: Option<F>, value: i32) -> bool
where
F: Fn(i32) -> bool + 'static
{
if let Some(f) = f {
f(value)
}
else {
value % 2 == 0
}
}
fn main() {
// The compiler does not like this. Removing the comment makes it work.
assert_eq!(take_optional_f(None /* ::<fn(i32) -> bool> */, 1), false);
}
Example of why I stumbled on this in Leptos:
#[component]
fn Button<F, IV>(
#[prop(optional)] icon: Option<F>,
// other "props", not important right now
) -> impl IntoView
where
F: Fn() -> IV + Send + Sync + Clone + 'static,
IV: IntoView + 'static,
{
// Button implementation here.
}
fn UseButton() -> impl IntoView {
// Note that we don't need to pass "icon" here, but obviously
// it will not work because the compiler doesn't know about
// the type of `F` above.
view! {
<Button class="filled" />
}
}
2 posts - 2 participants
🏷️ Rust_feed