Repository navigation
Tracking issue for RFC 3519: arbitrary_self_types #44874
Description
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:
- Fix the current lifetime elision bugs
- Search for potentially conflicting method candidates
- Block generic arbitrary self types.
- Introduce an
arbitrary_self_types_pointersfeature gate - Rename the old
Receivertrait -- currently being run through crater - Land the new
Receivertrait without it doing anything. - Switch over the method resolution to use the
Receivertrait, if thearbitrary_self_typesfeature is enabled. The main event. - Add diagnostics for the
!Sizedcase and theNonNulletc. cases. - Update the Rust reference.
- Add documentation to the dev guide. See the instructions.
- Add formatting for new syntax to the style guide. See the nightly style procedure.
- Decide whether
DerefandReceivertraits should be decoupled (cc @dingxiangfei2009). - (In the alternate:) Make
Derefa subtrait ofReceiver. - Clear out stabilization blockers.
- Stabilize!
Unresolved Questions
None.
Notable for Stabilization
Related
Implementation history
- Fix ambiguous cases of multiple & in elided self lifetimes #117967
- Arbitrary self types v2: pointers feature gate. #129664
- Reject generic self types. #130098
- Rename Receiver -> LegacyReceiver #130225
- Arbitrary self types v2: (unused) Receiver trait #132144
- Arbitrary self types v2: main compiler changes #132961
- Arbitrary self types v2: adjust diagnostic. #134262
- Arbitrary self types v2: Weak & NonNull diagnostics #134264
- Arbitrary self types v2: better feature gate test #134271
- Arbitrary self types v2: niche deshadowing test #134509
- Arbitrary self types v2: roll loop. #134521
- Arbitrary self types v2: no deshadow pre feature. #134524
- Arbitrary self types v2: unstable doc updates. #134525
- Arbitrary self types v2: explain test. #136124
(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 #27941 (comment)
Handling of inference variables
Calling a method on *const _ could now pick impls of the form
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
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.
trait MyStuff {
fn do_async_task(self: Rc<Self>);
}
impl MyStuff for () {
fn do_async_task(self: Rc<Self>) {
// ...
}
}
Rc::new(()).do_async_stuff();
Activity
[-]Allow methods with arbitrary self-types[/-][+]Allow trait methods with arbitrary self-types[/+]porky11 commentedon Sep 28, 2017
Why would you need this?
Why wouldn't you write an impl like this:
I'd rather define the trait different. Maybe like this:
In this case, Rc would be a trait type. If every generic type implemented a specific trait (this could be implemented automatically for generic types) this seems more understandable to me.
cuviper commentedon Sep 28, 2017
This could only be allowed for
traitmethods, right?For inherent methods, I can't
impl Rc<MyType>, but ifimpl MyTypecan add methods withself: Rc<Self>, it seems like that would enable weird method shadowing.arielb1 commentedon Oct 1, 2017
@cuviper
This is still pending lang team decisions (I hope there will be at least 1 RFC) but I think it will only be allowed for trait method impls.
arielb1 commentedon Oct 1, 2017
@porky11
You can't implement anything for
Rc<YourType>from a crate that does not own the trait.arielb1 commentedon Oct 2, 2017
So changes needed:
fn(self: Rc<Self>)doesn't accidentally become object-safeRc<Self>methodsSimonSapin commentedon Oct 2, 2017
I’ll look into this.
arielb1 commentedon Oct 2, 2017
Note that this is only supported to work with trait methods (and trait impl methods), aka
and is NOT supposed to work for inherent impl methods:
SimonSapin commentedon Oct 6, 2017
I got caught in some more Stylo work that's gonna take a while, so if someone else wants to work on this in the meantime feel free.
kennytm commentedon Oct 6, 2017
Is this supposed to allow any type as long as it involves
Self? Or must it implDeref<Target=Self>?277 remaining items
Rollup merge of rust-lang#136764 - traviscross:TC/make-ptr_cast_add_a…
Unrolled build for rust-lang#136764
Rollup merge of #136764 - traviscross:TC/make-ptr_cast_add_auto_to_ob…
Rollup merge of #136764 - traviscross:TC/make-ptr_cast_add_auto_to_ob…
Rollup merge of #136764 - traviscross:TC/make-ptr_cast_add_auto_to_ob…
Bug 1639018 - Change `TaskRunnable::dispatch` to take owned runnables…
programmerjake commentedon Aug 7, 2025
There's a Zulip thread discussing if
DerefandReceivershould be related at all via trait bounds or blanket impls. I now think they should be unrelated.programmerjake commentedon Aug 26, 2025
Rename Receiver -> LegacyReceiver
Rollup merge of #130225 - adetaylor:rename-old-receiver, r=wesleywiser
Rename Receiver -> LegacyReceiver
Rollup merge of #130225 - adetaylor:rename-old-receiver, r=wesleywiser
programmerjake commentedon May 7, 2026
we might have our first
stduser of this feature (rather than just being anotherDereftype):Simd<T, N>: Receiver<Target = T>clarfonthey commentedon Oct 10, 2026
Before I just offer a PR to do this, is there anything particularly stopping us from adding
Receiverimpls forrc::Weakandsync::Weak?These seem perfectly in line with this RFC, and also cannot implement
Deref.programmerjake commentedon Oct 10, 2026
like
*mut T, they have a bunch of methods takingself, so those could conflict with user-provided methods