How do you implement deref in a generic type containing a dash in rust?

It would be pretty convenient to use Deref to generate & TraitType from a generic container, rather than calling instance.as_ref (). i.e:

(*my_container).do_thing(); 

vs.

 my_container.as_ref().do_thing(); 

For this, I tried to implement Deref in a container type, but I get this error:

 <anon>:9:28: 9:29 error: expected a reference to a trait [E0172] <anon>:9 impl<T> Deref for HasTrait<T + Send> { 

From:

 use std::ops::Deref; trait Foo {} struct HasTrait<T> { data:Box<T> } impl<T> Deref for HasTrait<T + Send> { type Target = T; fn deref<'a>(&'a self) -> &'a T { return self.as_ref(); } } struct IsFoo; unsafe impl Send for IsFoo {} impl Foo for IsFoo {} fn main() { let is_foo = IsFoo; let foo:Box<Foo> = box is_foo as Box<Foo>; let has_foo = HasTrait { data: foo }; let foo_ref:&Foo = *has_foo; } 

I tried to use? Sized to increase T borders to allow traits, but it didn’t help?

What is the right way to do this?

+1
source share
1 answer

It works:

 use std::ops::Deref; struct HasTrait<T: ?Sized> { data: Box<T> } impl<T: ?Sized> HasTrait<T> { fn as_ref(&self) -> &T { &*self.data } } impl<T: ?Sized> Deref for HasTrait<T> { type Target = T; fn deref<'a>(&'a self) -> &'a T { // ' self.as_ref() } } trait Foo {} struct IsFoo; impl Foo for IsFoo {} fn main() { let is_foo = IsFoo; let foo: Box<Foo> = box is_foo as Box<Foo>; let has_foo = HasTrait { data: foo }; let foo_ref: &Foo = &*has_foo; } 

Basically, your problem was not related to dimension. This is just HasTrait<T + Send> here:

 impl<T> Deref<T> for HasTrait<T + Send> 

doesn't make sense. T can be an arbitrary type, and something like u64 + Send does not make sense. Therefore, I am afraid you will not be able to restrict HasTrait to contain only traits and only for those Send types. There is simply no syntax for this, and I'm sure the type system does not support it.

+1
source

All Articles