Случай - это ложный положительный результат, который можно решить с помощью нелексического времени жизни. Но я не проверял в деталях, может быть, это было бы плохое взаимодействие с потоками.
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();
я добавлю две строки с комментарием, произойдет следующая ошибка:
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
Подписиworks()
а такжеerrors()
выглядят довольно похоже. Но, видимо, компилятор знает, что вы можете обмануть егоRefCell
потому что заемщик ведет себя по-разному.
Я могу даже «спрятать»RefCell
в моем другом типе, но компилятор все равно всегда делает правильно, нг (ошибки в случаеRefCell
может быть использован). Как компилятор знает все эти вещи и как это работает? Пропускает ли компилятор типы как «контейнер внутренней изменчивости» или что-то в этом роде?