What is wrong? no method found for type in the current scope


#1

I’m trying to implement a factory with a struct named Builder. It has a property to count created instances. This counting object may be used in several factories simultaniously. That is the idea. When I compile the code, the compiler gives me the error message:

error: no method named `superman` found for type `game::hero::Builder<&mut game::count::Count>` in the current scope

Here is the struct:

pub struct Builder<T> {
     count: T
}

impl <T> Builder<T> where T: Counting {

    pub fn new(count: &mut T) -> Builder<&mut T>  {
        Builder{
            count: count
       }
    }

    pub fn superman(&mut self, health: u32, damage: u32) -> Option<Superman> {
    
        match self.count.next() {
            None => None,
            Some(_) => {
                Some(Superman::new(health, damage))
            }
        }
    }
}

This is how I call it:

let mut count: Count = Count::new(2);

let mut hero_builder = game::hero::Builder::new(&mut count); // <-- Dependency Injection
let mut hero = match hero_builder.superman(150, 20) {
    None => panic!("No heros left"),
    Some(hero) => hero
};

#2

I’m pretty sure your problem here is that even if Counting is implemented for the type Count, it isn’t implemented for &mut Count.

Try making a builder of game::hero::Builder<game::count::Count>. This could either be with your current definition, just with the Count as owned, rather than &mut, or define Builder with count: &mut T rather than count: T.

In any case, if you are going to depend on T: Counting, you are going to have to have T as just Count, not as an &mut Count.


#3

Thank you for a prompt answer! You are right. The implementation of the trait for &mut Count solved the problem.

But it still bothers me that I have to copypaste the methods. Is there a nice way to avoid it?

#[derive(Debug)]
pub struct Count {
    limit: u32,
    current: u32
}

pub trait Counting {
    fn next(&mut self) -> Option<u32>;
}


impl Count {
    pub fn new(limit: u32) -> Count {
        Count{
            limit: limit,
            current: 0
        }
    }
}

impl Counting for Count {
    fn next(&mut self) -> Option<u32> { // <-- here
        if self.current == self.limit {
            None
        } else {
            self.current = self.current + 1;
            Some(self.current)
        }
    }
}

impl <'a> Counting for &'a mut Count {
    fn next(&mut self) -> Option<u32> { // <-- and here
        if self.current == self.limit {
            None
        } else {
            self.current = self.current + 1;
            Some(self.current)
        }
    }
}

#4
impl <'a> Counting for &'a mut Count {
    fn next(&mut self) -> Option<u32> {
        Count::next(*self);
    }
}

should work ok for you. What that does is just call the implementation on Count itself, since the method already requires &mut self.

However, if you have many different things which implement Counting, a blanket implementation may be useful for you:

impl <'a, T> Counting for &'a mut T {
    fn next(&mut self) -> Option<u32> {
        T::next(*self);
    }
}

This would allow anything which implements Counting to work as both itself and as an &mut reference in Builder and anything else requiring `Counting.


#5

Dabo, thank you for helping me out of this problem! The project compiles and runs!

GitHub