简体   繁体   中英

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>`

You need to introduce an additional type parameter on the blanket impl for A :

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

After fixing that, you'll get a lifetime error since the trait object returned in the box infers a 'static lifetime, so you'll need to bind it to the input slice's 'a lifetime.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM