Repository: rust
Issue: trait object: specific use case of variance and/or coercion
Labels: A-trait-system,A-DSTs,T-compiler,C-bug,D-confusing,A-trait-objects

Filing this as a bug report because that's my best guess for what I believe is an inconsistency. Or perhaps simply the reference would need to be updated to explain the following.

> Note that I will use `<:` to denote a "subtype" relationship.

I tried this code:

```rust
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,
//      }
    }
}
```

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](https://doc.rust-lang.org/reference/subtyping.html#variance), `&'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](https://doc.rust-lang.org/reference/type-coercions.html#coercion-types). **Is this a bug?**

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). **Do we expect `Rc::get_mut(&mut self.module_rc)` to work, given that (1) works?**

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.68.0 (2c8cc3432 2023-03-06)
binary: rustc
commit-hash: 2c8cc343237b8f7d5a3c3703e3a87f2eb2c54a74
commit-date: 2023-03-06
host: aarch64-apple-darwin
release: 1.68.0
LLVM version: 15.0.6
```

<details><summary>Backtrace</summary>
<p>

```
error: lifetime may not live long enough
  --> fool/src/main.rs:21:9
   |
19 |     fn mut_rc<'s>(&'s mut self) -> Option<&'s mut (dyn Module + 's)> {
   |               -- lifetime `'s` defined here
20 |         // this doesn't work
21 |         Rc::get_mut(&mut self.module_rc) // : Option<&'s mut (dyn Module + 'static)>
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'s` must outlive `'static`
   |
   = note: requirement occurs because of a mutable reference to `dyn Module`
   = note: mutable references are invariant over their type parameter
   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: could not compile `rust` due to previous error
```

</p>
</details>