How to "erase" generic type in function arguments

⚓ Rust    📅 2025-10-16    👤 surdeus    👁️ 8      

surdeus

Warning

This post was published 47 days ago. The information described in this article may have changed.

The 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);
}

(Playground)

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

Read full topic

🏷️ Rust_feed