¿Quién tomó prestada una variable?
Estoy peleando con el verificador de préstamos. Tengo dos piezas de código similares, una que funciona como esperaba y la otra no.
El que funciona como espero:
mod case1 {
struct Foo {}
struct Bar1 {
x: Foo,
}
impl Bar1 {
fn f<'a>(&'a mut self) -> &'a Foo {
&self.x
}
}
// only for example
fn f1() {
let mut bar = Bar1 { x: Foo {} };
let y = bar.f(); // (1) 'bar' is borrowed by 'y'
let z = bar.f(); // error (as expected) : cannot borrow `bar` as mutable more
// than once at a time [E0499]
}
fn f2() {
let mut bar = Bar1 { x: Foo {} };
bar.f(); // (2) 'bar' is not borrowed after the call
let z = bar.f(); // ok (as expected)
}
}
El que no lo hace:
mod case2 {
struct Foo {}
struct Bar2<'b> {
x: &'b Foo,
}
impl<'b> Bar2<'b> {
fn f(&'b mut self) -> &'b Foo {
self.x
}
}
fn f4() {
let foo = Foo {};
let mut bar2 = Bar2 { x: &foo };
bar2.f(); // (3) 'bar2' is borrowed as mutable, but who borrowed it?
let z = bar2.f(); // error: cannot borrow `bar2` as mutable more than once at a time [E0499]
}
}
Esperaba poder llamarBar2::f
dos veces sin irritar al compilador, como en el caso 1.
La pregunta está en el comentario (3): quién pidió prestadobar2
, mientras que no hay afectación?
Esto es lo que entiendo:
En el caso 1,f2
llamada: el parámetro de por vida'a
es el del receptor&Foo
valor, por lo que esta vida útil está vacía cuando no hay afectación, ybar
no es prestado después delBar1::f
llamada;
En el caso 2,bar2
prestamosfoo
(como inmutable), por lo que el parámetro de vida útil'b
enBar2
struct es elfoo
vida útil de referencia, que termina al final def4
cuerpo. VocaciónBar2::f
prestamosbar2
para esa vida, es decir, hasta el final def4
.
Pero la pregunta sigue siendo: ¿quién pidió prestado?bar2
? Podría serBar2::f
? CómoBar2::f
retendría la propiedad prestada después de la llamada? ¿Que me estoy perdiendo aqui?
Estoy usando Rust 1.14.0-nightly (86affcdf6 2016-09-28) en x86_64-pc-windows-msvc.