1

So I'm storing trait objects behind Rc::Weak references as part of an implementation of the Observer Pattern in Rust, and I'm running into an issue where I try to store a Weak<T> inside of a Vec<Weak<dyn MyTrait>>, where T is a concrete instance of a type that implements MyTrait. Here's my minimum reproducible example:

use std::rc::{Rc, Weak};

trait MyTrait {}
struct Concrete {}
impl MyTrait for Concrete {}

struct Bucket {
    vec: Vec<Weak<dyn MyTrait>>,
}

impl Bucket {
    pub fn push(&mut self, to_push: Weak<dyn MyTrait>) {
        self.vec.push(to_push);
    }
}

fn main() {
    let bucket = Bucket { vec: Vec::new(), };
    let concrete = Concrete {};
    bucket.push(Rc::downgrade(&Rc::new(concrete)));
}

And here's the error:

error[E0308]: mismatched types
  --> src/main.rs:20:31
   |
20 |  bucket.push(Rc::downgrade(&Rc::new(concrete)));
   |                            ^^^^^^^^^^^^^^^^^^ expected trait object `dyn MyTrait`, found struct `Concrete`
   |
   = note: expected reference `&Rc<dyn MyTrait>`
          found reference `&Rc<Concrete>`

What I'm not understanding is how Concrete, which implements MyTrait, is not acceptable as a "dyn MyTrait" trait object. Concrete is MyTrait, so... what's happening here?

Currently running rustc 1.49.0 on stable, but this error occurs on the playground too.

Thanks for your time.

  • 3
    Theres probably a duplicate for this somewhere, but this is a flaw in rusts inference, you need to force the type downgrade to happen before the borrow: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=64987f81f8ef23b8134055673422fdf9 – user1937198 Apr 03 '21 at 20:28
  • @user1937198 Ah, thank you! – Jerome St.Martin Apr 03 '21 at 21:12

0 Answers0