---
# System prepended metadata

title: 'Do we stabilize Receiver now or wait for #[derive(SmartPointer)]?'

---

Do we stabilize `Receiver` now or wait for `#[derive(SmartPointer)]`?

## The decision

Do we:

* Stabilize a `Receiver` trait, without any special support for dynamic dispatch, allowing us to add more traits later for types which wish to support dynamic dispatch
* _Instead_ stabilize `#[derive(SmartPointer)]`, which currently might only `impl Receiver` but in future will also implement `DispatchFromDyn` (or whatever else is required to support dynamic dispatch).

If we're sure that we'll always want smart pointers to `#[derive(SmartPointer)]`, then we can reduce our future compatibility burden by not exposing `Receiver` additionally.

## Related material

* [`DispatchFromDyn`](https://doc.rust-lang.org/std/ops/trait.DispatchFromDyn.html)
* Arbitrary self types [design meeting minutes](https://hackmd.io/@rust-lang-team/rk2biy6n6)
* Notes on the RfL [needs](https://hackmd.io/@rust-lang-team/HymfJSLa6) and specifically on the [rationale for why this derive might be good](https://hackmd.io/@rust-lang-team/HymfJSLa6#Will-the-deriveSmartPointer-proposal-work-for-Rust-for-Linux)
* [RFC/minutes for this new `#derive`](https://hackmd.io/@rust-lang-team/HyYXScDa6)

## Questions

* Are there any use-cases for smart pointers where we would not want dynamic dispatch?
* Are there any types which might want to implement `Receiver` which are not smart pointers?

If the answer to either of these is "yes" then that's a definite reason to allow direct `impl` of `Receiver` instead of wrapping it up into`#[derive(SmartPointer)]`.

## C++ dynamic dispatch use-cases

Summary: `DispatchFromDyn` is harmless but probably not useful, and might be confusing. It would be better if we could implement `Receiver` without `DispatchFromDyn.`

Details:

Imagine we have:

```cpp
class Base {
public:
    virtual void Method() const;
};

class Derived : public Base {
public:
    virtual void Method() const;
};
```

We would like to be able to call that in Rust like this:

```rust
fn some_function() {
    let cpp_ptr: CppPtr<Base> = obtain_from_cpp();
    cpp_ptr.Method(); // may call Base::Method or Derived::Method
}
```

We couldn't use trait objects for this. It seems more likely that we'd want to call into some C++ shim function which does the dynamic dispatch according to C++'s precise vtable rules. (Cross-language inlining should make this free of overhead).

Most likely, the shim would look something like this:

```cpp
void CallBaseMethod(const Base* b) {
    b->Method();
}
```

I am confident we would not use trait objects for C++ dispatch.

Are they actively harmful? Not really, but having two types of dynamic dispatch here might be confusing.

## Rust for Linux usecases

Summary: there are some types which want to implement `Receiver` and _definitely cannot_ implement `DispatchFromDyn`.

Details:

Rust for Linux has at least one type where they _do_ want to implement `Receiver` but do not and _cannot_ implement `DispatchFromDyn`:

This is the [`Wrapper` type described here](https://rust-for-linux.com/arc-in-the-linux-kernel#nextprev-pointers-and-dynamic-dispatch):

```rust
struct Wrapper<T: ?Sized> {
    next: *mut Wrapper<T>,
    prev: *mut Wrapper<T>,
    value: T,
}
```

This isn't actually a _pointer_ so can't support dynamic dispatch.

## Conclusion

We must allow implementation of `Receiver` without implementing `DispatchFromDyn`, and therefore we should proceed with exposing `Receiver` intead of wrapping them up together into `#[derive(SmartPointer)]`.