0

I am implementing a struct with a generic bounded to a trait, but that implementation is desirable to feature functions that bound the generic even more. Below is the example:

struct A<T> {
   data: T
}

impl <T: AsRef<[u8]>> A<T> {
    fn test(&self, t: &T) {}
    fn more_bound<S: AsRef<[u8]> + PartialEq>(&self, t: &S) {
        self.test(t);  
    }
}

Playground

I cannot really use a specialization as I don't implement a trait. Neither would I like to define a trait. Are there any other options except changing the signature of test to fn test(&self, t: &impl AsRef<[u8]>) {}? Because such an approach seems to defeat the purpose of generics (in this case).

3

1 Answer 1

2

The compiler throws an error because in more_bound you take an S and then pass it into test, which requires a T. The fact that S and T are both AsRef<[u8]> (and T is weaker than S) is irrelevant since those generics have to match a fixed, concrete type (you promised a &T but gave an &S - who knows what &S is).

You can simply split the impl into two parts:

impl<T: AsRef<[u8]>> A<T> {
    fn test(&self, t: &T) {}
}

impl<T: AsRef<[u8]> + PartialEq> A<T> {
    fn more_bound(&self, t: &T) {
        self.test(t);
    }
}

The second impl will only be applicable for a T that is AsRef<[u8]> + PartialEq. As this bound guarantees that this T is AsRef<[u8]>, the more_bound method can call test, defined in the first impl.

If your original goal was to allow more_bound to be called with different types, you'll have to do the type-conversion via AsRef yourself:

impl <T: AsRef<[u8]>> A<T> {
    // Notice `test`takes the target of `AsRef<[u8]>`
    fn test(&self, t: &[u8]) {}

    fn more_bound<S: AsRef<[u8]> + PartialEq>(&self, t: &S) {
        // `S` can be whatever we want, it never "meets" `T`.
        self.test(t.as_ref()); 
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Wow, so simple. Not sure why I did not try it myself!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.