2

Consider the following (playground)

trait Module {}

struct Foo {
    module_box: Box<dyn Module + 'static>,
    module_rc: Rc<dyn Module + 'static>,
}

impl Foo {
    fn mut_box<'s>(&'s mut self) -> &'s mut (dyn Module + 's) {
        // this works
        self.module_box.as_mut() // : &'s mut (dyn Module + 'static)
    }

    fn mut_rc<'s>(&'s mut self) -> Option<&'s mut (dyn Module + 's)> {
        // this doesn't work
        Rc::get_mut(&mut self.module_rc) // : Option<&'s mut (dyn Module + 'static)>
        
        // but this does
//      match Rc::get_mut(&mut self.module_rc) {
//        Some(m) => Some(m),
//        None => None,
//      }
    }
}

Note: I will use <: to denote a subtype relationship

I have 2 related questions:

  1. why does the mut_box() implementation work?
  2. why doesn't the mut_rc() implement work?

For (1), I first assumed that subtyping/variance was the reason, since (dyn Module + 'static) <: (dyn Module + 's) (although I wasn't able to 100% confirm). However, according to the reference, &'a mut T is invariant over T; so if I'm reading this correctly, &'s mut (dyn Module + 'static) is NOT a subtype of &'s mut (dyn Module + 's). I then thought maybe an implicit coercion could then explain why it compiled, but was not able to find one in the list of coercion types.

Question (2) is very similar, except that the whole thing is wrapped in an Option, which seems to be the reason why it fails; the commented-out code unwraps the Option, which I believe sends us back to (1).

plafer
  • 185
  • 12
  • 2
    This is mysterious indeed. It looks like none of these variations should work, so the main question is why some of the actually do. – Sven Marnach Mar 09 '23 at 14:49
  • I don't have time to dig into that now, but maybe it is reborrowing? – Chayim Friedman Mar 09 '23 at 15:29
  • Reborrowing shouldn't be able to coerce incompatible types. I really can't understand why this works. I don't think it's a soundsness problem, but neither do I think the rules of the language as documented allow for this. – Sven Marnach Mar 10 '23 at 10:28

0 Answers0