New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trait inheritance gives unexpected compile error when inherited traits use associated types defined in trait #35237

Open
Osspial opened this Issue Aug 3, 2016 · 3 comments

Comments

Projects
None yet
5 participants
@Osspial

Osspial commented Aug 3, 2016

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

cc @jonathandturner @arielb1

@clarcharr

This comment has been minimized.

Contributor

clarcharr commented Jun 17, 2017

Bumping this to say that I just ran into this problem too. I think that we should at least improve the error to recommend the change because that's not clear at all from the error.

@vitalyd

This comment has been minimized.

vitalyd commented Jul 12, 2017

@SillyFreak

This comment has been minimized.

SillyFreak commented Jun 23, 2018

I just ran into this as well. I guess the problem with Self::Bar is that the compiler thinks about what Self could be in a concrete instance, instead of just looking at the trait being defined?

I think this warrants at least a changed error message, if not some cleaner way to "quote" the use of Self in this situation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment