Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
How can I define a method on [&mut T] where T: MyTrait?
I'm trying to make a trait method callable on mutable slices of a type implementing that trait (see main
). Rust doesn't like me for it.
use core::convert::AsMut;
trait A {
type B;
fn f(m: &mut [Self], b: Self::B);
}
impl<B, M: AsMut<[impl A<B=B>]>> M {
fn f(&mut self, b: B) {
A::f(self.as_mut(), b)
}
}
struct C (u64);
impl A for C {
type B = u8;
fn f(m: &mut [Self], b: u8) {
for c in m {
c.0 += b;
}
}
}
fn main() {
let v = vec![C(1), C(2), C(3), C(4)];
v.f(5);
assert_eq!(v, [C(6), C(7), C(8), C(9)]);
}
This gives me errors I don't understand, which is unusual for Rust:
Compiling playground v0.0.1 (/playground)
error[E0207]: the type parameter `B` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:8:6
|
8 | impl<B, M: AsMut<[impl A<B=B>]>> M {
| ^ unconstrained type parameter
error[E0207]: the type parameter `impl A<B = B>` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:8:19
|
8 | impl<B, M: AsMut<[impl A<B=B>]>> M {
| ^^^^^^^^^^^ unconstrained type parameter
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0207`.
error: could not compile `playground`.
Rewording my code slightly doesn't fix this. Is what I'm trying to do even possible in Rust? If so, how?
1 answer
This error doesn't do a good job at all of highlighting the important thing!
You can't define an inherent impl
on a type parameter. You have to make it the impl
of some trait. Here's an example: Try it online!
trait A: Sized {
type B;
fn f(m: &mut [Self], b: Self::B);
}
trait AsMutExt<Inner: A> {
fn f(&mut self, b: Inner::B);
}
impl<Inner: A, M: AsMut<[Inner]>> AsMutExt<Inner> for M {
fn f(&mut self, b: Inner::B) {
A::f(self.as_mut(), b)
}
}
#[derive(PartialEq, Debug)]
struct C (u64);
impl A for C {
type B = u8;
fn f(m: &mut [Self], b: u8) {
for c in m {
c.0 += b as u64;
}
}
}
fn main() {
let mut v = vec![C(1), C(2), C(3), C(4)];
v.f(5);
assert_eq!(v, [C(6), C(7), C(8), C(9)]);
}
0 comment threads