The trait `Clone` is not implemented for `&mut T`

Hi, Getting the error: the trait Clone is not implemented for &mut T. Any help or pointer please?

pub trait Indicator
{
    type Item;

    fn get_input_series(&self) -> CandleSeries;

    fn get_input_series_len(&self) -> usize;

    fn get_value(&mut self, index: usize) -> Option<Self::Item>;

    fn get_last_value(&mut self) -> Option<Self::Item> {
        let len: usize = self.get_input_series_len();
        self.get_value(len - 1)
    }

    fn get_all_values(&mut self) -> Vec<Option<Self::Item>>;

    fn calculate(&mut self, index: usize) -> Option<Self::Item>;

    fn calculate_all(&mut self) -> Vec<Option<Self::Item>>;
}

#[derive(PartialOrd, PartialEq, Clone, Debug)]
pub struct EMAIndicator<'ema, T>
    where T: Indicator + Clone {
    indicator: &'ema mut T,
    period: usize,
    multiplier: f64,
    calc_indicator_values: Vec<Option<f64>>,
}
error[E0277]: the trait bound `&mut T: Clone` is not satisfied
   --> src/traits.rs:281:5
    |
281 |     indicator: &'ema mut T,
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&mut T`
    |
    = help: the following implementations were found:
              <&T as Clone>
              <&mut T as Clone>
    = note: `Clone` is implemented for `&T`, but not for `&mut T`
    = note: required by `clone`
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

This can't possibly work. Cloning a mutable reference would create two mutable references to the same location. This is not allowed. There must either be a single mutable reference or any number of immutable references.

2 Likes

Solution? How to approach this in Rust?

What is it exactly that you want? Why does EMAIndicator need to be cloned and why is indicator a mutable reference instead of immutable reference?

I follow what you are saying, and the reason I want to Clone it is because I have PriceIndicator which is then used to create multiple EMAIndicator inside MACDIndicator. So basically, how to address this problem for the new of MACDIndicator i.e. how do I use the Indicator field and the other field such as short_term_period and long-term_period. Also Mutable Reference because they contain vector which holds the cached results to avoid re-calcs.

#[derive(PartialOrd, PartialEq, Clone, Debug)]
pub struct EMAIndicator<'ema, T>
    where T: Indicator + Clone {
    indicator: &'ema mut T,
    period: usize,
    multiplier: f64,
    calc_indicator_values: Vec<Option<f64>>,
}

#[derive(Debug)]
pub struct MACDIndicator<'macd, T>
    where T: Indicator + Clone {
    indicator: &'macd mut T,
    short_term_period: usize,
    long_term_period: usize,
    signal_line_period: usize,
    calc_indicator_values: Vec<Option<f64>>,
    calc_macd_values: Vec<Option<f64>>,
    calc_signal_values: Vec<Option<f64>>,
    calc_histogram_values: Vec<Option<f64>>,
    short_term_ema_indicator: EMAIndicator<'macd, T>,
    long_term_ema_indicator: EMAIndicator<'macd, T>,
}

impl<'macd, T> MACDIndicator<'macd, T>
    where T: Indicator + Clone {
    pub fn new(indicator: T) -> Self {
        Self {
            indicator,
            short_term_period: 12,
            long_term_period: 26,
            signal_line_period: 9,
            calc_indicator_values: Vec::new(),
            calc_macd_values: Vec::new(),
            calc_signal_values: Vec::new(),
            calc_histogram_values: Vec::new(),
            short_term_ema_indicator: EMAIndicator::new(indicator.clone(), 12),
            long_term_ema_indicator: EMAIndicator::new(indicator.clone(), 26),
        }
    }

You could try to use &'ema RefCell<T>.

Was trying to add RefCell. Is that the only possibility? Also from Design perspective it should be simpler than this and I may be doing something incorrect.

That is about the only possibility. There are also types like Cell and once_cell::unsync::OnceCell that are more specialized, but also more limited. You will have to use interior mutability in some way to mutate through an immutable reference.

oh ok, thanks. But this problem might crop in several places. If you happen to think of a better solution to this please let me know. Again thanks a lot for your time and help.

Warm Regards,

And the reason I was trying to avoid RefCell is that it will be slower isn't it ?

If you need to mutate some value from multiple places, there always be some kind of performance hit, to ensure the absence of data races,

1 Like

yes kind of makes sense and I think I need to rethink my design a bit more. Should not have had to do this as I never change the values for the PriceIndicators. It's the wrappers with the calculated values that need to be mutable. Also, I am yet not sure, inside the new method, is there a possibility to refer to another field? Still need to read the Rust Book :slight_smile:

Eek, that's not a helpful help. There's definitely not a Clone for &mut T impl. I've filed a bug about it:

9 Likes

Thank you so much @scottmcm. Finding the Rust community here to be one of the most amazing!