Esse erro ocorre devido ao conhecimento especial do compilador sobre o 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();
Se eu colocar as duas linhas com o comentário, ocorrerá o seguinte erro:
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
As assinaturas deworks()
eerrors()
parece bastante semelhante. Mas aparentemente o compilador sabe que você pode traí-lo com umRefCell
, porque o verificador de empréstimo se comporta de maneira diferente.
Eu posso até "esconder" oRefCell
em outro tipo, mas o compilador ainda sempre faz o que é certo (erros no caso de umRefCell
poderia ser usado). Como o compilador conhece todas essas coisas e como funciona? O compilador marca tipos como "contêiner de mutabilidade interior" ou algo assim?