Automatic trait implementation does not work

On the code below, you can see that I forced the implementation of A for everything that implements AsRef<[T]> and Index[T], so B should implement it, because it implements both of these. However this is not the case. Why?

use std::convert::{AsMut, AsRef};
use std::ops::{Index, IndexMut};
use std::slice::SliceIndex;

pub trait A<T, I: SliceIndex<[T], Output = T>>:
    AsRef<[T]> + Index<I, Output = T> 
{
    fn len(&self) -> usize;
}

impl<
        T: AsRef<[T]>  + Index<I, Output = T>,
        I: SliceIndex<[T], Output = T>,
    > A<T, I> for T
{
    fn len(&self) -> usize {
        self.as_ref().len()
    }
}

struct B<'a, T>{
    data: &'a mut [T]
}

impl<'a, T> AsRef<[T]> for B<'a, T> {
    fn as_ref(&self) -> &[T] {
        self.data
    }
}


impl<'a, T, I: SliceIndex<[T], Output = T>> Index<I> for B<'a, T> {
    type Output = T;

    fn index(
        &self,
        v: I,
    ) -> &Self::Output {
        &self.as_ref()[v]
    }
}


fn something<'a, T>(r: &'a mut[T]) -> Box<dyn A<T, usize>> {
    let a = B{data: r};
    Box::new(a)
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=aa2353139f3d097e2497ed700d678ed3

Error:

error[E0277]: the trait bound `B<'_, T>: A<T, usize>` is not satisfied
  --> src/lib.rs:46:5
   |
46 |     Box::new(a)
   |     ^^^^^^^^^^^ the trait `A<T, usize>` is not implemented for `B<'_, T>`
   |
   = note: required for the cast to the object type `dyn A<T, usize, Output = T>`

It looks like your impl is trying to use the type variable T for both the implementing type and the element type. (T: AsRef<[T]> is probably wrong.) Give them separate type variables and see how it works then.

1 Like