roidand
roidand

Reputation: 23

Why am I getting recursion when trying to implement trait for all reference types

I'm new to rust and having trouble implementing traits. Let me know if I'm going about this the wrong way. I'm trying to setup a trait with two functions for accessing a value. The get_value seems to function properly but when trying to setup the set_value with the &mut self reference, I'm getting the following error

warning: function cannot return without recursing
 --> src\main.rs:7:5
  |
7 |     fn set_value(&mut self, new_value: bool) {
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
8 |         (*self).set_value(new_value);
  |         ---------------------------- recursive call site
  |
  = note: `#[warn(unconditional_recursion)]` on by default
  = help: a `loop` may express intention better if this is on purpose

warning: 1 warning emitted

Example code:

trait Trait1 {
    fn set_value(&mut self, new_value: bool);
    fn get_value(&self) -> bool;
}

impl<'a, T> Trait1 for &'a T where T: Trait1 {
    fn set_value(&mut self, new_value: bool) {
        (*self).set_value(new_value);
    }
    fn get_value(&self) -> bool {
        (*self).get_value()
    }
}

impl<'a, T> Trait1 for &'a mut T where T: Trait1 {
    fn set_value(&mut self, new_value: bool) {
        (**self).set_value(new_value)
    }    
    fn get_value(&self) -> bool {
        (**self).get_value()
    }
}

struct Foo {
    value: bool
}

impl Trait1 for Foo {
    fn set_value(&mut self, new_value: bool) {
        self.value = new_value;
    }
    fn get_value(&self) -> bool {
        self.value
    }
}

fn main() {
    
}

Upvotes: 2

Views: 2435

Answers (1)

isaactfa
isaactfa

Reputation: 6651

You're getting the recursion error, because you only deref self once, turning it into a &T -- the type you're currently trying to implement the trait for -- while you want to get at a T. You don't get that error if you deref it twice like you do in the impl for &mut T.

You'll get another error, though, namely that that implementation won't work. You can't just deref a shared reference and then borrow a mutable reference from the referent. *self is a &T. You can't get a &mut T from that no matter how much you deref it.

Upvotes: 5

Related Questions