-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Comments
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. |
Another example of the same confusion: https://users.rust-lang.org/t/using-phantomdata-to-deal-with-unused-type-parameter/11799 |
I just ran into this as well. I guess the problem with I think this warrants at least a changed error message, if not some cleaner way to "quote" the use of |
cc @rust-lang/wg-diagnostics not sure on the false positive rate on this, but maybe we could just preemptively lint on Alternatively we can try hooking into the cycle error. It already knows it's in the supertrait computation. If y'all agree on doing stuff in cycle errors is the right place to do it, I can extend the query system to allow us to add more notes to the cycle error on a per-query basis. |
It feels to me that it should be accepted code, but I think that decision falls under @rust-lang/lang's purview. If they decide against it, then either proposed solution seems fine, with the former looking easiest to implement. Even if we decide to fix this so the code compiles it'd be nice to have a better message with a suggestion in the meantime. |
If we can straightforwardly accept this, I think we should. |
I think I just found out a trivial way of making this work for associated types on the base trait. What do we want to do for super traits, like the following case? trait Foo: AsRef<Self::Bar> {
type Bar;
}
trait Bar: Foo + AsRef<Self::Bar> {} I can easily make the first one work, but for the later 1) I don't know how easy it will be to make it work, but probably doable, 2) don't know if we want to make it work when there's a single unambiguous assoc type that can be used from a super trait 3) I would imagine if more than one assoc type that could match we would want to error like we do for assoc fns:
|
I think it's fine if it just works for the trait Foo {
type Bar;
}
trait Bar: Foo + AsRef<<Self as Bar>::Bar> {} then we get
and keeping this behaviour in a first PR seems totally reasonable to me |
I got the behavior I was aiming at last night and just published a cleaned up PR with it. It works in exactly the way you would expect. The following builds: trait Foo {
type Bar;
}
trait Qux: Foo + AsRef<Self::Bar> {}
trait Foo2 {}
trait Qux2: Foo2 + AsRef<Self::Bar> {
type Bar;
} and the following fails because of ambiguity, providing a good suggestion: trait Foo {
type Bar;
}
trait Qux: Foo + AsRef<Self::Bar> { //~ ERROR ambiguous associated type `Bar` in bounds of `Self`
type Bar;
}
The code has a special case when it recognizes it is converting an hir path written like @joshtriplett I don't know if that PR qualifies as straight-forward :) |
Skip the recursive evaluation of super-traits that reference associated types on `Self` directly (without using a fully-qualified path) in order to allow its use. The following code would previously emit a cycle evaluation error and will now successfuly compile: ```rust trait Bar<T> { fn foo() -> T; } trait Foo: Bar<Self::Qux> { type Qux; } ``` The following will also work: ```rust trait Bar<T> { fn foo() -> T; } trait Baz { type Qux; } trait Foo: Bar<Self::Qux> + Baz {} ``` Fix rust-lang#35237.
should this be re-opened, given that the fix got a revert |
Should have been closed by #80732 |
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:
which throws this 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:
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 theBar
type, only requiring the usage ofas
if the associated type is part of a supertrait. For example, take the following traitBaz
with the associated typeA
: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 theBaz
trait. The programmer would also expect usingSelf::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 theas
syntax to specify the supertrait that the associated type is coming from.Meta
Rust version:
cc @jonathandturner @arielb1
The text was updated successfully, but these errors were encountered: