Compilation errors about generic trait

struct S {}
fn foo() {}
trait T<Rhs> {
    fn t(&self, rhs: Rhs);
}
impl T<fn()> for S {
    fn t(&self, _: fn()) {}
}
//impl T<i32> for S {
//    fn t(&self, _: i32) {}
//}

fn main() {
    let s = S {};

    // if comment `impl T<i32> for S', below two lines can compile
    s.t(foo);
    s.t(foo as fn());

    // if uncomment `impl T<i32> for S', only below line can compile
    // how to compile `s.t(foo)' in this case?
    s.t(foo as fn());
}

Please read the pinned formatting post linked below and edit your post accordingly. The code visible doesn't compile, probably because some code is being interpreted as invalid html, and the question is unclear to me.

3 Likes

Thanks for your tips. Updated already.

You need

impl<F: Fn()> T<F> for S {
    fn t(&self, _: F) {}
}

For detail, see

https://doc.rust-lang.org/reference/types/function-item.html
https://doc.rust-lang.org/reference/types/function-pointer.html

1 Like

It's about the type inference/coercion on generics. Say if there is a single type parameter, Rust can infer and may coerce it easily . But if the type conversion is vague due to multiple implementations, you'd have to covert the type manually/explicitly.

foo, the function item, is easily coerced to a function pointer (fn type), so the s.t(foo); passes when single implememtation exists.

When there are multiple implememtations, i.e. S: T<fn()> and S: T<i32>, the coercion failed to happen because it happens after the step where the type resolution is done, causing error[E0308]: mismatched types or error[E0277]: the trait bound S: T<fn() {foo}> is not satisfied you see.

1 Like

In my opinion, `s.t(foo)' should not compile, too.
Is this a compiler bug?

// if comment `impl T<i32> for S', below two lines can compile
    s.t(foo);
    s.t(foo as fn());

Thanks.
Seems reasonable, is there any official document for this?

I believe it's documented in rustc-dev book, like Trait solving - Rust Compiler Development Guide.
I haven't thorough read it. But Canonical queries - Rust Compiler Development Guide and Canonicalization - Rust Compiler Development Guide seem related here.

It's not a bug. You want things to coerce automatically most times.

https://doc.rust-lang.org/reference/type-coercions.html