Repository: rust
Issue: Tracking issue for RFC 3519: `arbitrary_self_types`
Labels: B-RFC-approved,T-lang,B-unstable,C-tracking-issue,F-arbitrary_self_types,S-tracking-needs-summary,T-types,S-types-deferred

This is the tracking issue for RFC 3519: Arbitrary self types v2.

The feature gate for this issue is `#![feature(arbitrary_self_types)]`.

### About tracking issues

Tracking issues are used to record the overall progress of implementation.  They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.  A tracking issue is however *not* meant for large scale discussion, questions, or bug reports about a feature.  Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

### Steps

[Current plan][] is:

[Current plan]: https://github.com/rust-lang/rust/issues/44874#issuecomment-2122179688
 
* [x] **Fix the current lifetime elision bugs** 
* [x] **Search for potentially conflicting method candidates** 
* [x] **Block generic arbitrary self types**. 
* [x] **Introduce an `arbitrary_self_types_pointers` feature gate**
* [x] **Rename the old `Receiver` trait** -- currently being run through crater
* [x] **Land the new `Receiver` trait without it doing anything**.
* [x] **Switch over the method resolution to use the `Receiver` trait, if the `arbitrary_self_types` feature is enabled**. The main event.
* [ ] **Add [diagnostics](https://github.com/rust-lang/rust/issues/44874) for the `!Sized` case and the `NonNull` etc. cases.**
* [ ] **Update the Rust reference**.
* [ ] Add documentation to the [dev guide][]. See the [instructions][doc-guide].
* [ ] Add formatting for new syntax to the [style guide][]. See the [nightly style procedure][].
* [ ] Stabilize!
  - https://github.com/rust-lang/rust/pull/135881

[dev guide]: https://github.com/rust-lang/rustc-dev-guide
[doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs
[nightly style procedure]: https://github.com/rust-lang/style-team/blob/master/nightly-style-procedure.md
[reference]: https://github.com/rust-lang/reference
[reference-instructions]: https://github.com/rust-lang/reference/blob/master/CONTRIBUTING.md
[style guide]: https://github.com/rust-lang/rust/tree/master/src/doc/style-guide

### Unresolved Questions

None.

### Notable for Stabilization

- https://github.com/rust-lang/rust/pull/134524

### Related

- #27941

### Implementation history

TODO.

---

*(Below follows content that predated the accepted Arbitrary Self Types v2 RFC.)*

<details>

- [ ] figure out the object safety situation
- [ ] figure out the handling of inference variables behind raw pointers
- [ ] decide whether we want safe virtual raw pointer methods

## Object Safety

See https://github.com/rust-lang/rust/issues/27941#issuecomment-332157526

## Handling of inference variables

Calling a method on `*const _` could now pick impls of the form
```Rust
impl RandomType {
    fn foo(*const Self) {}
}
```

Because method dispatch wants to be "limited", this won't really work, and as with the existing situation on `&_` we should be emitting an "the type of this value must be known in this context" error.

This feels like fairly standard inference breakage, but we need to check the impact of this before proceeding.

## Safe virtual raw pointer methods

e.g. this is UB, so we might want to force the call `<dyn Foo as Foo>::bar` to be unsafe somehow - e.g. by not allowing `dyn Foo` to be object safe unless `bar` was an `unsafe fn`

```Rust
trait Foo {
    fn bar(self: *const Self);
}

fn main() {
    // creates a raw pointer with a garbage vtable
    let foo: *const dyn Foo = unsafe { mem::transmute([0usize, 0x1000usize]) };
    // and call it
    foo.bar(); // this is UB
}
```

However, even today you could UB in safe code with `mem::size_of_val(foo)` on the above code, so this might not be actually a problem.

## More information

There's no reason the `self` syntax has to be restricted to `&T`, `&mut T` and `Box<T>`, we should allow for more types there, e.g.

```Rust
trait MyStuff {
    fn do_async_task(self: Rc<Self>);
}

impl MyStuff for () {
    fn do_async_task(self: Rc<Self>) {
        // ...
    }
}

Rc::new(()).do_async_stuff();
```

</details>