> Я подозреваю, что дело в том, что Mutex в ядре self-referential структура,
> поэтому его надо припинить, и инициализировать после. И вот здесь ты
> замучаешься с MaybeUnint выкручиваться, чтобы сокрыть unsafe.Посмотрел сейчас код, и суть мне теперь понятна
```
let data = Pin::from(Box::try_new(unsafe { Mutex::new_uninit(0) })?);
mutex_init!(data.as_ref(), "RustExample::init::data1");
```
Тут всё на самом деле проще, каждому мьютексу нужен класс (static переменная на месте использования), который создаётся макросом init_with_lockdep, который вызывается из mutex_init. Аналогично с CondVar и прочими, смотри доки к NeedsLockClass и init_with_lockdep
Мьютекс созданный через new класса не имеет, соответственно им пользоваться нельзя, и потому new - unsafe
В данном случае это пока нельзя внести в макрос, т.к макрос вида
```
macro_rules! new_mutex {
($var:ident, $name:lit, $value:expr) => {
let $var = Pin::from(Box::try_new(unsafe { Mutex::new_uninit($value) })?);
mutex_init!(data.as_ref(), $name);
}
}
new_mutex!(data, "RustExample::init::data1", 0);
```
Не сработает, т.к тут создаётся отдельный блок, а static переменные так объявлять нельзя (Подводит гигиена макросов)
И внутрь Mutex создание класса не внести, т.к const generics ещё не стабилизировали, и специализировать Mutex по строковому названию класса соответственно тоже не выйдет
Поэтому тут решили поступить достаточно грубо, и просто разнесли создание мьютекса (Mutex::new) и присвоение ему класса (включая собственно создание этого класса, mutex_init) в 2 строки
И по идее, это можно было бы избежать, сделав отдельный макрос для инициализации класса, и чтобы Mutex::new принимал этот класс:
```
new_class!(MY_CLASS, "RustExample::init::data1");
Mutex::new(MY_CLASS, 0);
```
Однако так не сделали, чтобы быть ближе к сишному апи (https://github.com/torvalds/linux/blob/d310ec03a34e92a77302e...), и чтобы никто случайно не использовал один класс для двух разных мьютексов.
Однако я так думаю, что если эта тема будет продвигаться, то для этого и некоторых других случаев просто напишут процедурный макрос (Если const generics не релизнутся раньше, сейчас они в бете).
У них нет гигиены, а соответственно в них всякие такие вещи реализуются красивее)