An error about trait Deref

The following code can not compile(playground):

use std::ops::Deref;

pub trait RollApply<T, N> {
    fn roll_func(&self, f: fn(x: &[T]) -> T, n: usize) -> Vec<N>;
}



impl RollApply<f32, f32> for [f32] {
    fn roll_func(&self, f: fn(x: &[f32]) -> f32, n: usize) -> Vec<f32> {
        let mut res = Vec::with_capacity(self.len());
        for i in 0..self.len() {
            let res_ = if i < n - 1 {
                f32::NAN
            } else {
                f(&self[i + 1 - n .. i + 1])
            };
            res.push(res_);
        }
        res
    }
}



impl<T, N> RollApply<T, Vec<T>> for Vec<N>
where  
    [T]: RollApply<T, T>,
    N: AsRef<[T]>,
{
    fn roll_func(&self, f: fn(x: &[T]) -> T, n: usize) -> Vec<Vec<T>> {
        self.iter().map(|x| x
            .deref()
            .roll_func(f, n)).collect()
    }
}

fn max(data: &[f32]) -> f32 {
    *data.iter().max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
}

fn main() {

    let data1 = vec![1f32, 2., 3., 4., 5.];
    let data2 = vec![2f32, 3., 4., 5., 6.];
    let data3 = vec![data1.clone(), data2.clone()];
    let data4 = vec![&data1, &data2];
    let data5 = vec![&data1[..], &data2[..]];

    let _test1 = data1.roll_func(max, 3);
    let _test2 = data1[..].roll_func(max, 3);
    let _test3 = data3.roll_func(max, 3);
    let _test4 = data4.roll_func(max, 3);
    let _test4 = data5.roll_func(max, 3);

}

This is the error:

  Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `roll_func` found for reference `&N` in the current scope
  --> src/main.rs:34:14
   |
34 |             .roll_func(f, n)).collect()
   |              ^^^^^^^^^ method not found in `&N`
   |
   = help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `roll_func`, perhaps you need to restrict type parameter `N` with it:
   |
29 |     N: AsRef<[T]> + RollApply,
   |                   +++++++++++

For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` due to previous error

I can not understand this. In my understanding, when I am calling the line self.iter().map(|x| x.deref().roll_func(f, n)) from trait implementation, firstly by the step self.iter().map(|x| x) I get N: AsRef<[T]>, and by Self.iter().map(|x| x.deref()) I get [T] and [T]: RollAplly<T, T> implied by the trait bound. So it seems has method roll_func, but it has no. What am I getting wrong?

You are confusing AsRef and Deref. Nothing in your code calls AsRef::as_ref(); the deref impl for a regular reference simply produces itself. Accordingly, this compiles.

1 Like

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.