4

I have the following code:

struct X { i: i32 }

trait MyTrait<T> {
    fn hello(&self);
}

impl MyTrait<i32> for X {
    fn hello(&self) { println!("I'm an i32") }
}

impl MyTrait<String> for X {
    fn hello(&self) { println!("I'm a String") }
}

fn main() {
    let f = X { i: 0 };
    f.hello();
}

which obviously does not compile as the compiler cannot disambiguate to which trait the f.hello() belongs. So I'm getting the error

error[E0282]: type annotations needed
  --> src\main.rs:17:7
   |
17 |     f.hello();
   |       ^^^^^ cannot infer type for type parameter `T` declared on the trait `MyTrait`

Is there any way to annotate the type of hello so I can tell the compiler to e.g. invoke MyTrait<String>::hello on f?

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Commenting to link to [How do I disambiguate traits in Rust?](/questions/44953197/how-do-i-disambiguate-traits-in-rust) and also [How to call a method when a trait and struct use the same method name?](/questions/44445730/how-to-call-a-method-when-a-trait-and-struct-use-the-same-method-name) – trent May 16 '20 at 14:41

2 Answers2

6

After some digging in I bumped into the "Fully Qualified Syntax for Disambiguation: Calling Methods with the Same Name" from the Rust Book. The situation can be adapted to mine, and one can use f as a receiver for the corresponding trait method

<X as MyTrait<String>>::hello(&f);

This compiles and works as intended.

Or even

<MyTrait<String>>::hello(&f);

works.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
5

You can use fully qualified function call syntax:

fn main() {
    let f: X;

    // shorthand form
    MyTrait::<String>::hello(&f);

    // expanded form, with deduced type
    <_ as MyTrait<String>>::hello(&f);

    // expanded form, with explicit type
    <X as MyTrait<String>>::hello(&f);
}

Run in Playground

Frxstrem
  • 38,761
  • 9
  • 79
  • 119