Closed
Description
The following program fails to compile:
trait Foo { fn foo(&self, x: &Self); }
trait Bar<A: Foo> { fn bar(&self) -> A; }
struct Wrap<T>(T);
impl<A, B: Bar<A>> Wrap<B> {
fn test(&self, x: &A) {
(*self).bar().foo(x);
}
}
fn main() {}
With the following error:
implsearch.rs:8:8: 8:22 error: failed to find an implementation of trait Foo for A
implsearch.rs:8 (*self).bar().foo(x);
^~~~~~~~~~~~~~
Given that B: Bar<A>
, we know A: Foo
because of the definition of the trait Bar. This can be seen as a generalized case of trait inheritance (trait B inheriting from A lets us know that if X:B
, then X:A
, because X:B
requires X:A
; similarly, B:Bar<A>
requires A:Foo
, so we know A:Foo
). Indeed, in Haskell there is no distinction between the two forms of inheritance:
{-# LANGUAGE MultiParamTypeClasses #-}
class Foo b where foo :: b -> b -> ()
class Foo b => Bar a b where bar :: a -> b
test :: Bar a b => a -> b -> ()
test x y = foo (bar x) y
The order of arguments to Bar could be switched and the program above would still be valid.