How to "erase" generic type in function arguments

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

surdeus

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