0

I'm trying to do a simple Arc downcast:

use std::any::Any;
use std::sync::{Arc, Mutex};

pub struct OnTheFlySwap<T: Sized> {
    inner: Arc<Mutex<Option<Box<T>>>>,
}

pub trait LockableOption<T: Sized>: Send + Sync + Any {}

impl<T: Sized + Send + 'static> LockableOption<T> for OnTheFlySwap<T> {}

struct ArcHolder<U: Sized> {
    lockable_option: Arc<dyn LockableOption<U>>,
}

impl<U: 'static + Send + Sync + Sized> ArcHolder<U> {
    pub fn as_on_the_fly(&self) -> Result<&OnTheFlySwap<U>, ()> {
        let l: Arc<dyn Any + Send + Sync> = self.lockable_option;
        match l.downcast::<OnTheFlySwap<U>>() {
            Ok(o) => Ok(&o),
            Err(_) => Err(()),
        }
    }
}

Playground

but I get

error[E0308]: mismatched types
  --> src/lib.rs:18:45
   |
18 |         let l: Arc<dyn Any + Send + Sync> = self.lockable_option;
   |                --------------------------   ^^^^^^^^^^^^^^^^^^^^ expected trait `Any + Send + Sync`, found trait `LockableOption<U>`
   |                |
   |                expected due to this
   |
   = note: expected struct `Arc<(dyn Any + Send + Sync + 'static)>`
              found struct `Arc<(dyn LockableOption<U> + 'static)>`

The only thing I can think of is that dyn LockableOption<U> is somehow not implementing Any. I don't see any other possible problems.

What is happening?

Guerlando OCs
  • 1,886
  • 9
  • 61
  • 150
  • Here's a simple reproduction of the same issue: [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8e60c6b4718d1d3418bc7438e3d662e6). I'm pretty sure that there is a duplicate answer somewhere, but the short of it is that you can't assign an `Arc` to an `Arc` (or `Box`) even if `B: A`. – Jmb Jul 08 '21 at 06:41
  • See also: https://stackoverflow.com/questions/49543778/why-cant-i-cast-a-box-with-an-extended-trait-to-a-box-with-the-base-trait?r=SearchResults&s=3|87.2642 – Jmb Jul 08 '21 at 06:47

0 Answers0