I seem to have come across a rather strange interaction between associated types, lifetimes, and where
clauses on methods. Playground
I was able to reduce the original code to this:
trait Trait {
type Associated;
// In the original, this method took parameters and was generic, and the
// constraint here was dependent on those generics, so this can't just be
// moved to `type Associated : Default`.
fn method() where Self::Associated : Default;
}
struct Struct<'a, 'b>(&'a (), &'b ());
// Problem here
// Changing `'b: 'a` to just `'b` resolves the compiler error.
// Note that in the real code, there actually is a need for this lifetime
// constraint (and it's present on `Struct` as well).
impl<'a, 'b: 'a> Trait for Struct<'a, 'b> {
type Associated = ();
fn method() { }
}
fn main() { }
which produces the incredibly unhelpful errors
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
--> <anon>:19:5
|
19 | fn method() { }
| ^^^^^^^^^^^^^^^
|
help: consider using an explicit lifetime parameter as shown: fn method()
--> <anon>:19:5
|
19 | fn method() { }
| ^^^^^^^^^^^^^^^
error: aborting due to previous error
(This was on nightly, but essentially the same issue also appears on beta and stable.)
The error is dependent on both the lifetime constraint 'b: 'a
(which in the original code was also on the struct declaration) and the where Self::Associated
constraint in the trait (which was also replicated to the impl
method in the original). Removing either of those makes the code compile, even though there's no way obvious to me for the two to interact.
I'd appreciate any light that could be shed on this; I'm honestly not sure whether there's actually something wrong with the code or if I've run into some odd corner case in the compiler.