Description
If one defines a trait such that inherited traits involve one of the trait's associated types, the compiler throws a "cyclic reference" error when one does not need to be thrown. Take the following code:
trait Foo: AsRef<Self::Bar> {
type Bar;
}
which throws this error:
error: unsupported cyclic reference between types/traits detected [--explain E0391]
--> <anon>:1:18
1 |> trait Foo: AsRef<Self::Bar> {
|> ^^^^^^^^^
note: the cycle begins when computing the supertraits of `Foo`...
note: ...which then again requires computing the supertraits of `Foo`, completing the cycle.
error: aborting due to previous error
This error, while it accurately describes what is happening inside of the compiler, does not actually provide any way to fix the error. Even worse, the situation where the error arises isn't consistent with how associated types work in other areas of the trait syntax.
Making the above code work is fairly simple, although it does unnecessarily clutter the trait definition. The following compiles:
trait Foo: AsRef<<Self as Foo>::Bar> {
type Bar;
}
However, this is not an immediately obvious fix due to how referencing associated types work in other areas of the trait syntax. In all other areas, the as
syntax is unnecessary if the associated type is a member of the trait being implemented, which is true of the Bar
type, only requiring the usage of as
if the associated type is part of a supertrait. For example, take the following trait Baz
with the associated type A
:
trait Baz {
type A;
fn do_something(&self) -> Self::A;
}
This compiles, as expected. The compiler correctly infers that, because of the lack of as
syntax, the programmer is referring to a type belonging to the Baz
trait. The programmer would also expect using Self::A
to work when defining trait inheritance, although this is currently not the case. However, this should be the case - the compiler should, before throwing the "cyclic reference" error, scan the current trait for the given associated type and only throw the error if a type is not detected, as it does in other areas of trait definitions. The error should also outline the solution to the problem, suggesting that the programmer use the as
syntax to specify the supertrait that the associated type is coming from.
Meta
Rust version:
rustc 1.10.0 (cfcb716cf 2016-07-03)
binary: rustc
commit-hash: cfcb716cf0961a7e3a4eceac828d94805cf8140b
commit-date: 2016-07-03
host: x86_64-unknown-linux-gnu
release: 1.10.0