¿Es este error debido al conocimiento especial del compilador sobre RefCell?
fn works<'a>(foo: &Option<&'a mut String>, s: &'a mut String) {}
fn error<'a>(foo: &RefCell<Option<&'a mut String>>, s: &'a mut String) {}
let mut s = "hi".to_string();
let foo = None;
works(&foo, &mut s);
// with this, it errors
// let bar = RefCell::new(None);
// error(&bar, &mut s);
s.len();
Si pongo las dos líneas con el comentario, se produce el siguiente error:
error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable
--> <anon>:16:5
|
14 | error(&bar, &mut s);
| - mutable borrow occurs here
15 |
16 | s.len();
| ^ immutable borrow occurs here
17 | }
| - mutable borrow ends here
Las firmas deworks()
yerrors()
Se ve bastante similar. Pero aparentemente el compilador sabe que puedes engañarlo con unRefCell
, porque el verificador de préstamos se comporta de manera diferente.
Incluso puedo "ocultar" elRefCell
en otro tipo de la mía, pero el compilador todavía siempre hace lo correcto (errores en caso de queRefCell
puede ser usado). ¿Cómo sabe el compilador todas esas cosas y cómo funciona? ¿El compilador marca los tipos como "contenedor de mutabilidad interior" o algo así?