Почему небезопасная реализация Syn c и Send приводит к тому, что структура становится не 'stati c? - PullRequest
1 голос
/ 13 апреля 2020

Я хочу создать структуру, которая будет служить оболочкой для глобального 'static константа синглтона. Для этого я создал структуру Wrapper, содержащую указатель на T.

fn main() {
    let s = Box::new(TestStruct {}) as Box<dyn TestTrait>;
    let l = Wrapper::new(s);
    tokio::spawn(async move { l.run().await });
}

struct Wrapper<T: Send + Sync + 'static> {
    ptr: *const T,
    // _phantom: std::marker::PhantomData<T>, // Use instead of ptr for tests
}
impl<T: Send + Sync + 'static> Wrapper<T> {
    pub fn new(item: T) -> Self {
        todo!();
    }
}
impl<T: Send + Sync + 'static> std::ops::Deref for Wrapper<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        todo!();
    }
}
unsafe impl<T: Send + Sync + 'static> Sync for Wrapper<T> {}
unsafe impl<T: Send + Sync + 'static> Send for Wrapper<T> {}

trait TestTrait: Send + Sync {
    fn run(&self) -> futures::future::BoxFuture<()>;
}
struct TestStruct {}
impl TestTrait for TestStruct {
    fn run(&self) -> futures::future::BoxFuture<()> {
        todo!();
    }
}
error[E0477]: the type `std::boxed::Box<dyn TestTrait>` does not fulfill the required lifetime
 --> src/main.rs:4:5
  |
4 |     tokio::spawn(async move { l.run().await });
  |     ^^^^^^^^^^^^
  |
  = note: type must satisfy the static lifetime

Проблема странная, потому что, если я удаляю unsafe impls и заменяю ptr на _phantom, программа компилируется. Похоже, добавление unsafe impl с 'static временем жизни прерывает некоторые внутренние проверки.

Подводя итог:

  • нет указателя в структуре, нет unsafe impl s - нет ошибка
  • указатель в структуре, нет unsafe impl с - ошибка, потому что ptr не Sync + Send, это нормально
  • нет указателя в структуре, unsafe impl с - ошибка, не 'static (???)
  • указатель в структуре, unsafe impl s - ошибка, не 'static (???)

Имею прочитайте Как мне создать глобальный изменяемый синглтон? и Как создать безопасный статический синглтон c в Rust? . Меня не интересует, как создать глобальный синглтон, мне любопытно, почему мой пример не компилируется, будь то ошибка компилятора или где именно я ошибаюсь в своем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...