Consider the following (playpen):
trait Foo<'a> {
type Out: 'a;
}
fn foo<'a, T>(_: &'a mut T) -> <T as Foo<'a>>::Out where T : Foo<'a> {
unimplemented!()
}
fn baz<T>(mut x: T) where for<'a> T : Foo<'a>, for<'a> <T as Foo<'a>>::Out : 'static {
let y = foo(&mut x);
let z = foo(&mut x);
}
fn main() {
struct Bar;
impl<'a> Foo<'a> for Bar {
type Out = i32;
}
let mut b = Bar;
let y = foo(&mut b);
let z = foo(&mut b);
}
main compiles fine, as expected, since the associated type expands to i32, which does not use the lifetime 'a that the mutable reference input argument is bound by.
baz however fails to compile (error message below), despite the additional constraint on Out to be 'static, implying that the return value of foo does not borrow the argument.
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> src/main.rs:11:22
|
10 | let y = foo(&mut x);
| - first mutable borrow occurs here
11 | let z = foo(&mut x);
| ^ second mutable borrow occurs here
12 | }
| - first borrow ends here
This problem appears to be unique to unexpanded associated types, as they are the only case where the lifetime parameters do not directly determine the lifetime bounds on the type.
Consider the following (playpen):
maincompiles fine, as expected, since the associated type expands toi32, which does not use the lifetime'athat the mutable reference input argument is bound by.bazhowever fails to compile (error message below), despite the additional constraint onOutto be'static, implying that the return value offoodoes not borrow the argument.This problem appears to be unique to unexpanded associated types, as they are the only case where the lifetime parameters do not directly determine the lifetime bounds on the type.