use std::fmt::Debug; use std::ops::Add; use forward_traits::{forwardable, forward_receiver, forward_traits}; struct Algebra {} #[forwardable] trait AlgAdd { type Output; fn add (self, x: T, y: T) -> Self::Output; } impl AlgAdd for Algebra where T: Add { type Output = T; fn add (self, x: T, y: T) -> Self::Output { x + y } } #[allow (dead_code)] struct RefContainer <'a, T> (&'a T); #[forwardable] trait WeirdAsRef { type Borrowed <'a> where T: 'a; fn weird_as_ref <'a> (self, x: &'a T) -> Self::Borrowed <'a>; } impl WeirdAsRef for Algebra { type Borrowed <'a> = RefContainer <'a, T> where T: 'a; fn weird_as_ref <'a> (self, x: &'a T) -> Self::Borrowed <'a> { RefContainer (x) } } #[derive (Copy, Clone, PartialEq, Debug)] struct Wrap (T); impl From for Wrap { fn from (x: T) -> Self { Self (x) } } #[forward_receiver] struct WrapAlgebra {} impl Into for WrapAlgebra { fn into (self) -> Algebra { Algebra {} } } forward_traits! ( for WrapAlgebra -> Algebra [Wrap . 0: T, Self::Output -> Wrap ] where Wrap : Sized impl AlgAdd > ); forward_traits! ( for WrapAlgebra -> Algebra [ Wrap . 0: T, for <'a> Self::Borrowed <'a> -> Wrap > ] impl WeirdAsRef > ); fn main () { assert_eq! ( WrapAlgebra {} . add (Wrap:: (1.0), Wrap:: (2.0)), Wrap:: (3.0) ); }