---
name: Tracking Issue
-about: A tracking issue for a feature in Rust.
+about: A tracking issue for an accepted feature or RFC in Rust.
title: Tracking Issue for XXX
labels: C-tracking-issue
---
/// ```
#[stable(feature = "rc_raw", since = "1.17.0")]
pub fn into_raw(this: Self) -> *const T {
+ let ptr = Self::as_ptr(&this);
+ mem::forget(this);
+ ptr
+ }
+
+ /// Provides a raw pointer to the data.
+ ///
+ /// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
+ /// for as long there are strong counts in the `Rc`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(weak_into_raw)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let x = Rc::new("hello".to_owned());
+ /// let y = Rc::clone(&x);
+ /// let x_ptr = Rc::as_ptr(&x);
+ /// assert_eq!(x_ptr, Rc::as_ptr(&y));
+ /// assert_eq!(unsafe { &*x_ptr }, "hello");
+ /// ```
+ #[unstable(feature = "weak_into_raw", issue = "60728")]
+ pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr);
let fake_ptr = ptr as *mut T;
- mem::forget(this);
// SAFETY: This cannot go through Deref::deref.
// Instead, we manually offset the pointer rather than manifesting a reference.
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
///
- /// The pointer is valid only if there are some strong references. The pointer may be dangling
- /// or even [`null`] otherwise.
+ /// The pointer is valid only if there are some strong references. The pointer may be dangling,
+ /// unaligned or even [`null`] otherwise.
///
/// # Examples
///
/// let strong = Rc::new("hello".to_owned());
/// let weak = Rc::downgrade(&strong);
/// // Both point to the same object
- /// assert!(ptr::eq(&*strong, weak.as_raw()));
+ /// assert!(ptr::eq(&*strong, weak.as_ptr()));
/// // The strong here keeps it alive, so we can still access the object.
- /// assert_eq!("hello", unsafe { &*weak.as_raw() });
+ /// assert_eq!("hello", unsafe { &*weak.as_ptr() });
///
/// drop(strong);
- /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to
+ /// // But not any more. We can do weak.as_ptr(), but accessing the pointer would lead to
/// // undefined behaviour.
- /// // assert_eq!("hello", unsafe { &*weak.as_raw() });
+ /// // assert_eq!("hello", unsafe { &*weak.as_ptr() });
/// ```
///
/// [`null`]: ../../std/ptr/fn.null.html
#[unstable(feature = "weak_into_raw", issue = "60728")]
- pub fn as_raw(&self) -> *const T {
- match self.inner() {
- None => ptr::null(),
- Some(inner) => {
- let offset = data_offset_sized::<T>();
- let ptr = inner as *const RcBox<T>;
- // Note: while the pointer we create may already point to dropped value, the
- // allocation still lives (it must hold the weak point as long as we are alive).
- // Therefore, the offset is OK to do, it won't get out of the allocation.
- let ptr = unsafe { (ptr as *const u8).offset(offset) };
- ptr as *const T
- }
- }
+ pub fn as_ptr(&self) -> *const T {
+ let offset = data_offset_sized::<T>();
+ let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
+ ptr as *const T
}
/// Consumes the `Weak<T>` and turns it into a raw pointer.
/// can be turned back into the `Weak<T>` with [`from_raw`].
///
/// The same restrictions of accessing the target of the pointer as with
- /// [`as_raw`] apply.
+ /// [`as_ptr`] apply.
///
/// # Examples
///
/// ```
///
/// [`from_raw`]: struct.Weak.html#method.from_raw
- /// [`as_raw`]: struct.Weak.html#method.as_raw
+ /// [`as_ptr`]: struct.Weak.html#method.as_ptr
#[unstable(feature = "weak_into_raw", issue = "60728")]
pub fn into_raw(self) -> *const T {
- let result = self.as_raw();
+ let result = self.as_ptr();
mem::forget(self);
result
}
///
/// # Safety
///
- /// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was
- /// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
- /// count.
+ /// The pointer must have originated from the [`into_raw`] and must still own its potential
+ /// weak reference count.
///
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
/// [`upgrade`]: struct.Weak.html#method.upgrade
/// [`Rc`]: struct.Rc.html
/// [`Weak`]: struct.Weak.html
- /// [`as_raw`]: struct.Weak.html#method.as_raw
/// [`new`]: struct.Weak.html#method.new
/// [`forget`]: ../../std/mem/fn.forget.html
#[unstable(feature = "weak_into_raw", issue = "60728")]
/// ```
#[stable(feature = "rc_raw", since = "1.17.0")]
pub fn into_raw(this: Self) -> *const T {
+ let ptr = Self::as_ptr(&this);
+ mem::forget(this);
+ ptr
+ }
+
+ /// Provides a raw pointer to the data.
+ ///
+ /// The counts are not affected in way and the `Arc` is not consumed. The pointer is valid for
+ /// as long as there are strong counts in the `Arc`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(weak_into_raw)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let x = Arc::new("hello".to_owned());
+ /// let y = Arc::clone(&x);
+ /// let x_ptr = Arc::as_ptr(&x);
+ /// assert_eq!(x_ptr, Arc::as_ptr(&y));
+ /// assert_eq!(unsafe { &*x_ptr }, "hello");
+ /// ```
+ #[unstable(feature = "weak_into_raw", issue = "60728")]
+ pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
let fake_ptr = ptr as *mut T;
- mem::forget(this);
// SAFETY: This cannot go through Deref::deref.
// Instead, we manually offset the pointer rather than manifesting a reference.
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
///
- /// The pointer is valid only if there are some strong references. The pointer may be dangling
- /// or even [`null`] otherwise.
+ /// The pointer is valid only if there are some strong references. The pointer may be dangling,
+ /// unaligned or even [`null`] otherwise.
///
/// # Examples
///
/// let strong = Arc::new("hello".to_owned());
/// let weak = Arc::downgrade(&strong);
/// // Both point to the same object
- /// assert!(ptr::eq(&*strong, weak.as_raw()));
+ /// assert!(ptr::eq(&*strong, weak.as_ptr()));
/// // The strong here keeps it alive, so we can still access the object.
- /// assert_eq!("hello", unsafe { &*weak.as_raw() });
+ /// assert_eq!("hello", unsafe { &*weak.as_ptr() });
///
/// drop(strong);
- /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to
+ /// // But not any more. We can do weak.as_ptr(), but accessing the pointer would lead to
/// // undefined behaviour.
- /// // assert_eq!("hello", unsafe { &*weak.as_raw() });
+ /// // assert_eq!("hello", unsafe { &*weak.as_ptr() });
/// ```
///
/// [`null`]: ../../std/ptr/fn.null.html
#[unstable(feature = "weak_into_raw", issue = "60728")]
- pub fn as_raw(&self) -> *const T {
- match self.inner() {
- None => ptr::null(),
- Some(inner) => {
- let offset = data_offset_sized::<T>();
- let ptr = inner as *const ArcInner<T>;
- // Note: while the pointer we create may already point to dropped value, the
- // allocation still lives (it must hold the weak point as long as we are alive).
- // Therefore, the offset is OK to do, it won't get out of the allocation.
- let ptr = unsafe { (ptr as *const u8).offset(offset) };
- ptr as *const T
- }
- }
+ pub fn as_ptr(&self) -> *const T {
+ let offset = data_offset_sized::<T>();
+ let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
+ ptr as *const T
}
/// Consumes the `Weak<T>` and turns it into a raw pointer.
/// can be turned back into the `Weak<T>` with [`from_raw`].
///
/// The same restrictions of accessing the target of the pointer as with
- /// [`as_raw`] apply.
+ /// [`as_ptr`] apply.
///
/// # Examples
///
/// ```
///
/// [`from_raw`]: struct.Weak.html#method.from_raw
- /// [`as_raw`]: struct.Weak.html#method.as_raw
+ /// [`as_ptr`]: struct.Weak.html#method.as_ptr
#[unstable(feature = "weak_into_raw", issue = "60728")]
pub fn into_raw(self) -> *const T {
- let result = self.as_raw();
+ let result = self.as_ptr();
mem::forget(self);
result
}
///
/// # Safety
///
- /// The pointer must have originated from the [`into_raw`] (or [`as_raw'], provided there was
- /// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
- /// count.
+ /// The pointer must have originated from the [`into_raw`] and must still own its potential
+ /// weak reference count.
///
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
/// ```
///
- /// [`as_raw`]: struct.Weak.html#method.as_raw
/// [`new`]: struct.Weak.html#method.new
/// [`into_raw`]: struct.Weak.html#method.into_raw
/// [`upgrade`]: struct.Weak.html#method.upgrade
/// Below are common applications of `transmute` which can be replaced with safer
/// constructs.
///
+ /// Turning raw bytes(`&[u8]`) to `u32`, `f64`, etc.:
+ ///
+ /// ```
+ /// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
+ ///
+ /// let num = unsafe {
+ /// std::mem::transmute::<[u8; 4], u32>(raw_bytes);
+ /// };
+ ///
+ /// // use `u32::from_ne_bytes` instead
+ /// let num = u32::from_ne_bytes(raw_bytes);
+ /// // or use `u32::from_le_bytes` or `u32::from_ge_bytes` to specify the endianness
+ /// let num = u32::from_le_bytes(raw_bytes);
+ /// assert_eq!(num, 0x12345678);
+ /// let num = u32::from_be_bytes(raw_bytes);
+ /// assert_eq!(num, 0x78563412);
+ /// ```
+ ///
/// Turning a pointer into a `usize`:
///
/// ```
-The lang attribute is intended for marking special items that are built-in to
-Rust itself. This includes special traits (like `Copy` and `Sized`) that affect
-how the compiler behaves, as well as special functions that may be automatically
-invoked (such as the handler for out-of-bounds accesses when indexing a slice).
+The lang attribute was used in an invalid context.
+
Erroneous code example:
```compile_fail,E0522
loop {}
}
```
+
+The lang attribute is intended for marking special items that are built-in to
+Rust itself. This includes special traits (like `Copy` and `Sized`) that affect
+how the compiler behaves, as well as special functions that may be automatically
+invoked (such as the handler for out-of-bounds accesses when indexing a slice).
sig: &ty::FnSig<'_>,
ident: Ident,
predicates: ty::GenericPredicates<'_>,
+ assoc: &ty::AssocItem,
) -> String {
let args = sig
.inputs()
.iter()
- .map(|ty| {
+ .enumerate()
+ .map(|(i, ty)| {
Some(match ty.kind {
- ty::Param(param) if param.name == kw::SelfUpper => "self".to_string(),
- ty::Ref(reg, ref_ty, mutability) => {
+ ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
+ ty::Ref(reg, ref_ty, mutability) if i == 0 => {
let reg = match &format!("{}", reg)[..] {
"'_" | "" => String::new(),
reg => format!("{} ", reg),
};
- match ref_ty.kind {
- ty::Param(param) if param.name == kw::SelfUpper => {
- format!("&{}{}self", reg, mutability.prefix_str())
+ if assoc.fn_has_self_parameter {
+ match ref_ty.kind {
+ ty::Param(param) if param.name == kw::SelfUpper => {
+ format!("&{}{}self", reg, mutability.prefix_str())
+ }
+
+ _ => format!("self: {}", ty),
}
- _ => format!("_: {:?}", ty),
+ } else {
+ format!("_: {:?}", ty)
+ }
+ }
+ _ => {
+ if assoc.fn_has_self_parameter && i == 0 {
+ format!("self: {:?}", ty)
+ } else {
+ format!("_: {:?}", ty)
}
}
- _ => format!("_: {:?}", ty),
})
})
.chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
tcx.fn_sig(assoc.def_id).skip_binder(),
assoc.ident,
tcx.predicates_of(assoc.def_id),
+ assoc,
)
}
ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
const CONSTANT: u32;
type Type;
fn method(&self, s: String) -> Self::Type;
+ fn method2(self: Box<Self>, s: String) -> Self::Type;
+ fn method3(other: &Self, s: String) -> Self::Type;
+ fn method4(&self, other: &Self) -> Self::Type;
+ fn method5(self: &Box<Self>) -> Self::Type;
}
-error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `method`
+error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `method`, `method2`, `method3`, `method4`, `method5`
--> $DIR/m2.rs:9:1
|
LL | impl m1::X for X {
- | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method` in implementation
+ | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method`, `method2`, `method3`, `method4`, `method5` in implementation
|
= help: implement the missing item: `const CONSTANT: u32 = 42;`
= help: implement the missing item: `type Type = Type;`
= help: implement the missing item: `fn method(&self, _: std::string::String) -> <Self as m1::X>::Type { todo!() }`
+ = help: implement the missing item: `fn method2(self: std::boxed::Box<Self>, _: std::string::String) -> <Self as m1::X>::Type { todo!() }`
+ = help: implement the missing item: `fn method3(_: &Self, _: std::string::String) -> <Self as m1::X>::Type { todo!() }`
+ = help: implement the missing item: `fn method4(&self, _: &Self) -> <Self as m1::X>::Type { todo!() }`
+ = help: implement the missing item: `fn method5(self: &std::boxed::Box<Self>) -> <Self as m1::X>::Type { todo!() }`
error: aborting due to previous error