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?

questionAnswers(1)

yourAnswerToTheQuestion