Feature name: arbitrary_self_types
Stabilization target: 1.32.0
Tracking issue: #44874
Related RFCs: rust-lang/rfcs#2362
This is a proposal to stabilize a subset of the arbitrary_self_types feature,
making it possible on stable to use valid "arbitrary" self types that have been
defined in the standard library, but not to define your own new self types.
Stabilized feature or APIs
Today, only the following types are allowed as self types unless the user uses
the arbitrary_self_types flag:
Self
&Self
&mut Self
Box<Self>
We've long desired to extend this set to all pointer types defined in std, and
(ideally) to arbitrary user defined pointer types. For quite a while now, the
ability to create user defined self types has existed on nightly under the
arbitrary_self_types flag; in this stabilization, we propose to stabilize the
extension of self types to all the relevant pointer types defined in std and
their compositions, while leaving the ability to create your own self types
unstable for now while we iterate on the exact requirements.
The new self types that will be enabled by this stabilization are:
*const Self
*mut Self
Rc<Self>
Arc<Self>
Pin<P> where P is another type in this set.
The composition of any members in this set (e.g. &Box<Self>,
Pin<&mut Rc<Self>>).
Additionally, all of these receiver types except for Self are object safe, in
the sense that they can be used as the receivers of object-safe trait methods.
Object safety of raw pointer types
By making pointers object-safe, we have introduced an additional requirement on
raw pointers: a wide raw pointer must contain valid metadata, even if the
data pointer is null or dangling. That is, a *const dyn Trait must have
a metadata pointer pointing to a valid vtable for Trait.
As an alternative, we could possibly restrict this to only allowing raw
pointers as the receiver types for unsafe methods, and validity of the metadata
pointer would be an invariant the caller would be expected to uphold.
Non-Deref pointer types
Library defined pointer types can only be receiver types if they implement
Deref currently. This excludes certain std pointer types that don't implement
Deref, because they could be dangling:
NonNull<Self>
rc::Weak<Self>
sync::Weak<Self>
This stabilization is forward compatible with someday supporting these pointers
as receiver types as we continue to iterate on the requirements of defining
arbitrary self types.
Magic traits involved
It's worth noting that currently the implementation of this functionality
involves the intersection of several ops traits:
Deref - a self type must be deref, transitively targeting Self
CoerceUnsized
DispatchFromDyn - this and the previous are necessary for object safe
- (potentially)
Receiver - a private trait in std used to limit stabilization
only to these std traits
The interaction of this feature with these traits is not made stable as a
part of this proposal. The traits listed that are still unstable remain
unstable. We still have flexibility to iterate on the exact requirements on
arbitrary self types so long as those requirements include all of the types I
have enumerated previously.
Implementation changes prior to stabilization
Connected features and larger milestones
A trait making use of this feature is the Future trait, which is still
unstable under the futures_api feature:
trait Future {
type Output;
fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output>;
}
Before we can stabilize this trait, we need to stabilize the ability to
implement traits using Pin<&mut Self> as a receiver type: hence, this
stabilization. Stabilizing the futures_api feature is a high priority because
it is a blocker for stabilizing the async/await syntax, which makes nonblocking
IO much more ergonomic for Rust.
cc @mikeyhew
Feature name:
arbitrary_self_typesStabilization target: 1.32.0
Tracking issue: #44874
Related RFCs: rust-lang/rfcs#2362
This is a proposal to stabilize a subset of the
arbitrary_self_typesfeature,making it possible on stable to use valid "arbitrary" self types that have been
defined in the standard library, but not to define your own new self types.
Stabilized feature or APIs
Today, only the following types are allowed as self types unless the user uses
the
arbitrary_self_typesflag:Self&Self&mut SelfBox<Self>We've long desired to extend this set to all pointer types defined in std, and
(ideally) to arbitrary user defined pointer types. For quite a while now, the
ability to create user defined self types has existed on nightly under the
arbitrary_self_typesflag; in this stabilization, we propose to stabilize theextension of self types to all the relevant pointer types defined in std
and, while leaving the ability to create your own self typestheir compositions
unstable for now while we iterate on the exact requirements.
The new self types that will be enabled by this stabilization are:
*const Self*mut SelfRc<Self>Arc<Self>Pin<P>wherePis another type in this set.The composition of any members in this set (e.g.
&Box<Self>,Pin<&mut Rc<Self>>).Additionally, all of these receiver types except for
Selfare object safe, inthe sense that they can be used as the receivers of object-safe trait methods.
Object safety of raw pointer typesBy making pointers object-safe, we have introduced an additional requirement onraw pointers: a wide raw pointer must contain valid metadata, even if the
data pointer is null or dangling. That is, a
*const dyn Traitmust havea metadata pointer pointing to a valid vtable for
Trait.As an alternative, we could possibly restrict this to only allowing rawpointers as the receiver types for unsafe methods, and validity of the metadata
pointer would be an invariant the caller would be expected to uphold.
Non-
Derefpointer typesLibrary defined pointer types can only be receiver types if they implement
Derefcurrently. This excludes certain std pointer types that don't implementDeref, because they could be dangling:NonNull<Self>rc::Weak<Self>sync::Weak<Self>This stabilization is forward compatible with someday supporting these pointers
as receiver types as we continue to iterate on the requirements of defining
arbitrary self types.
Magic traits involved
It's worth noting that currently the implementation of this functionality
involves the intersection of several ops traits:
Deref- a self type must be deref, transitively targetingSelfCoerceUnsizedDispatchFromDyn- this and the previous are necessary for object safeReceiver- a private trait in std used to limit stabilizationonly to these std traits
The interaction of this feature with these traits is not made stable as a
part of this proposal. The traits listed that are still unstable remain
unstable. We still have flexibility to iterate on the exact requirements on
arbitrary self types so long as those requirements include all of the types I
have enumerated previously.
Implementation changes prior to stabilization
Receivertrait to limit stable self types to those defined in std(@mikeyhew is working on this)
Adjust documentation and diagnostics to note the additional valid
receiver types defined in std, instead of only the 4 accepted today
Connected features and larger milestones
A trait making use of this feature is the
Futuretrait, which is stillunstable under the
futures_apifeature:Before we can stabilize this trait, we need to stabilize the ability to
implement traits using
Pin<&mut Self>as a receiver type: hence, thisstabilization. Stabilizing the
futures_apifeature is a high priority becauseit is a blocker for stabilizing the async/await syntax, which makes nonblocking
IO much more ergonomic for Rust.
cc @mikeyhew