Rust can't see trait implementations for bounded generics?

When I try to compile this code:

mod module {
    impl<T: Trait> Trait for &mut T {
        fn method(self) {}
    }
    
    pub trait Trait {
        fn method(self);
    }
}

fn test<T: module::Trait>(object: &mut T) {
    // use module::Trait; // uncomment to get rid of the error
    object.method();
    
    // or do this instead
    // module::Trait::method(object);
}

link to playground

I get the following error: error[E0507]: cannot move out of `*object` which is behind a mutable reference. Basically, rust tries to call method from Trait, instead of method from the implementation block for &mut Trait. The most confusing thing for me here is that adding use module::Trait gets rid of the error.

So, why is there an error in the first place, and how does adding a use declaration help?

Trait methods are usable in two cases:

  • either the trait must be imported into current scope,
  • or it must be guaranteed by the bound.

In your case, the bound guarantees that Trait is implemented for T, but not for &mut T - therefore, when trait is not in scope, function isn't allowed to use the knowledge that &mut T implements Trait too. When you import it, however, the usual method resolution rules kick in, with implementation for &mut T taking precedence.

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.