mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-04 14:07:36 +00:00
Auto merge of #71326 - Dylan-DPC:rollup-hdlkdj5, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #71107 (Address concerns of weak-into-raw) - #71188 (Fixed missing trait method suggests incorrect code (self parameter not named "self"). ) - #71300 (Clarify when to use the tracking issue template) - #71315 (Add example in the alternative in std::mem::transmute docs) - #71319 (Clean up E0522 explanation) Failed merges: r? @ghost
This commit is contained in:
commit
1b7dec9e44
2
.github/ISSUE_TEMPLATE/tracking_issue.md
vendored
2
.github/ISSUE_TEMPLATE/tracking_issue.md
vendored
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: Tracking Issue
|
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
|
title: Tracking Issue for XXX
|
||||||
labels: C-tracking-issue
|
labels: C-tracking-issue
|
||||||
---
|
---
|
||||||
|
@ -569,9 +569,33 @@ impl<T: ?Sized> Rc<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rc_raw", since = "1.17.0")]
|
#[stable(feature = "rc_raw", since = "1.17.0")]
|
||||||
pub fn into_raw(this: Self) -> *const T {
|
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 ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr);
|
||||||
let fake_ptr = ptr as *mut T;
|
let fake_ptr = ptr as *mut T;
|
||||||
mem::forget(this);
|
|
||||||
|
|
||||||
// SAFETY: This cannot go through Deref::deref.
|
// SAFETY: This cannot go through Deref::deref.
|
||||||
// Instead, we manually offset the pointer rather than manifesting a reference.
|
// Instead, we manually offset the pointer rather than manifesting a reference.
|
||||||
@ -1644,8 +1668,8 @@ impl<T> Weak<T> {
|
|||||||
|
|
||||||
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
|
/// 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
|
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
|
||||||
/// or even [`null`] otherwise.
|
/// unaligned or even [`null`] otherwise.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -1658,32 +1682,23 @@ impl<T> Weak<T> {
|
|||||||
/// let strong = Rc::new("hello".to_owned());
|
/// let strong = Rc::new("hello".to_owned());
|
||||||
/// let weak = Rc::downgrade(&strong);
|
/// let weak = Rc::downgrade(&strong);
|
||||||
/// // Both point to the same object
|
/// // 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.
|
/// // 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);
|
/// 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.
|
/// // undefined behaviour.
|
||||||
/// // assert_eq!("hello", unsafe { &*weak.as_raw() });
|
/// // assert_eq!("hello", unsafe { &*weak.as_ptr() });
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`null`]: ../../std/ptr/fn.null.html
|
/// [`null`]: ../../std/ptr/fn.null.html
|
||||||
#[unstable(feature = "weak_into_raw", issue = "60728")]
|
#[unstable(feature = "weak_into_raw", issue = "60728")]
|
||||||
pub fn as_raw(&self) -> *const T {
|
pub fn as_ptr(&self) -> *const T {
|
||||||
match self.inner() {
|
|
||||||
None => ptr::null(),
|
|
||||||
Some(inner) => {
|
|
||||||
let offset = data_offset_sized::<T>();
|
let offset = data_offset_sized::<T>();
|
||||||
let ptr = inner as *const RcBox<T>;
|
let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
|
||||||
// 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
|
ptr as *const T
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consumes the `Weak<T>` and turns it into a raw pointer.
|
/// Consumes the `Weak<T>` and turns it into a raw pointer.
|
||||||
///
|
///
|
||||||
@ -1691,7 +1706,7 @@ impl<T> Weak<T> {
|
|||||||
/// can be turned back into the `Weak<T>` with [`from_raw`].
|
/// can be turned back into the `Weak<T>` with [`from_raw`].
|
||||||
///
|
///
|
||||||
/// The same restrictions of accessing the target of the pointer as with
|
/// The same restrictions of accessing the target of the pointer as with
|
||||||
/// [`as_raw`] apply.
|
/// [`as_ptr`] apply.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -1712,10 +1727,10 @@ impl<T> Weak<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`from_raw`]: struct.Weak.html#method.from_raw
|
/// [`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")]
|
#[unstable(feature = "weak_into_raw", issue = "60728")]
|
||||||
pub fn into_raw(self) -> *const T {
|
pub fn into_raw(self) -> *const T {
|
||||||
let result = self.as_raw();
|
let result = self.as_ptr();
|
||||||
mem::forget(self);
|
mem::forget(self);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@ -1730,9 +1745,8 @@ impl<T> Weak<T> {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was
|
/// The pointer must have originated from the [`into_raw`] and must still own its potential
|
||||||
/// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
|
/// weak reference count.
|
||||||
/// count.
|
|
||||||
///
|
///
|
||||||
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak 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
|
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
|
||||||
@ -1765,7 +1779,6 @@ impl<T> Weak<T> {
|
|||||||
/// [`upgrade`]: struct.Weak.html#method.upgrade
|
/// [`upgrade`]: struct.Weak.html#method.upgrade
|
||||||
/// [`Rc`]: struct.Rc.html
|
/// [`Rc`]: struct.Rc.html
|
||||||
/// [`Weak`]: struct.Weak.html
|
/// [`Weak`]: struct.Weak.html
|
||||||
/// [`as_raw`]: struct.Weak.html#method.as_raw
|
|
||||||
/// [`new`]: struct.Weak.html#method.new
|
/// [`new`]: struct.Weak.html#method.new
|
||||||
/// [`forget`]: ../../std/mem/fn.forget.html
|
/// [`forget`]: ../../std/mem/fn.forget.html
|
||||||
#[unstable(feature = "weak_into_raw", issue = "60728")]
|
#[unstable(feature = "weak_into_raw", issue = "60728")]
|
||||||
|
@ -566,9 +566,33 @@ impl<T: ?Sized> Arc<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rc_raw", since = "1.17.0")]
|
#[stable(feature = "rc_raw", since = "1.17.0")]
|
||||||
pub fn into_raw(this: Self) -> *const T {
|
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 ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
|
||||||
let fake_ptr = ptr as *mut T;
|
let fake_ptr = ptr as *mut T;
|
||||||
mem::forget(this);
|
|
||||||
|
|
||||||
// SAFETY: This cannot go through Deref::deref.
|
// SAFETY: This cannot go through Deref::deref.
|
||||||
// Instead, we manually offset the pointer rather than manifesting a reference.
|
// Instead, we manually offset the pointer rather than manifesting a reference.
|
||||||
@ -1340,8 +1364,8 @@ impl<T> Weak<T> {
|
|||||||
|
|
||||||
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
|
/// 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
|
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
|
||||||
/// or even [`null`] otherwise.
|
/// unaligned or even [`null`] otherwise.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -1354,32 +1378,23 @@ impl<T> Weak<T> {
|
|||||||
/// let strong = Arc::new("hello".to_owned());
|
/// let strong = Arc::new("hello".to_owned());
|
||||||
/// let weak = Arc::downgrade(&strong);
|
/// let weak = Arc::downgrade(&strong);
|
||||||
/// // Both point to the same object
|
/// // 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.
|
/// // 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);
|
/// 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.
|
/// // undefined behaviour.
|
||||||
/// // assert_eq!("hello", unsafe { &*weak.as_raw() });
|
/// // assert_eq!("hello", unsafe { &*weak.as_ptr() });
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`null`]: ../../std/ptr/fn.null.html
|
/// [`null`]: ../../std/ptr/fn.null.html
|
||||||
#[unstable(feature = "weak_into_raw", issue = "60728")]
|
#[unstable(feature = "weak_into_raw", issue = "60728")]
|
||||||
pub fn as_raw(&self) -> *const T {
|
pub fn as_ptr(&self) -> *const T {
|
||||||
match self.inner() {
|
|
||||||
None => ptr::null(),
|
|
||||||
Some(inner) => {
|
|
||||||
let offset = data_offset_sized::<T>();
|
let offset = data_offset_sized::<T>();
|
||||||
let ptr = inner as *const ArcInner<T>;
|
let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
|
||||||
// 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
|
ptr as *const T
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consumes the `Weak<T>` and turns it into a raw pointer.
|
/// Consumes the `Weak<T>` and turns it into a raw pointer.
|
||||||
///
|
///
|
||||||
@ -1387,7 +1402,7 @@ impl<T> Weak<T> {
|
|||||||
/// can be turned back into the `Weak<T>` with [`from_raw`].
|
/// can be turned back into the `Weak<T>` with [`from_raw`].
|
||||||
///
|
///
|
||||||
/// The same restrictions of accessing the target of the pointer as with
|
/// The same restrictions of accessing the target of the pointer as with
|
||||||
/// [`as_raw`] apply.
|
/// [`as_ptr`] apply.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -1408,10 +1423,10 @@ impl<T> Weak<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`from_raw`]: struct.Weak.html#method.from_raw
|
/// [`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")]
|
#[unstable(feature = "weak_into_raw", issue = "60728")]
|
||||||
pub fn into_raw(self) -> *const T {
|
pub fn into_raw(self) -> *const T {
|
||||||
let result = self.as_raw();
|
let result = self.as_ptr();
|
||||||
mem::forget(self);
|
mem::forget(self);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@ -1427,9 +1442,8 @@ impl<T> Weak<T> {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// The pointer must have originated from the [`into_raw`] (or [`as_raw'], provided there was
|
/// The pointer must have originated from the [`into_raw`] and must still own its potential
|
||||||
/// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
|
/// weak reference count.
|
||||||
/// count.
|
|
||||||
///
|
///
|
||||||
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak 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
|
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
|
||||||
@ -1458,7 +1472,6 @@ impl<T> Weak<T> {
|
|||||||
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
|
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`as_raw`]: struct.Weak.html#method.as_raw
|
|
||||||
/// [`new`]: struct.Weak.html#method.new
|
/// [`new`]: struct.Weak.html#method.new
|
||||||
/// [`into_raw`]: struct.Weak.html#method.into_raw
|
/// [`into_raw`]: struct.Weak.html#method.into_raw
|
||||||
/// [`upgrade`]: struct.Weak.html#method.upgrade
|
/// [`upgrade`]: struct.Weak.html#method.upgrade
|
||||||
|
@ -1100,6 +1100,24 @@ extern "rust-intrinsic" {
|
|||||||
/// Below are common applications of `transmute` which can be replaced with safer
|
/// Below are common applications of `transmute` which can be replaced with safer
|
||||||
/// constructs.
|
/// 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`:
|
/// Turning a pointer into a `usize`:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
The lang attribute is intended for marking special items that are built-in to
|
The lang attribute was used in an invalid context.
|
||||||
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).
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0522
|
```compile_fail,E0522
|
||||||
@ -12,3 +10,8 @@ fn cookie() -> ! { // error: definition of an unknown language item: `cookie`
|
|||||||
loop {}
|
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).
|
||||||
|
@ -2251,26 +2251,39 @@ fn fn_sig_suggestion(
|
|||||||
sig: &ty::FnSig<'_>,
|
sig: &ty::FnSig<'_>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
predicates: ty::GenericPredicates<'_>,
|
predicates: ty::GenericPredicates<'_>,
|
||||||
|
assoc: &ty::AssocItem,
|
||||||
) -> String {
|
) -> String {
|
||||||
let args = sig
|
let args = sig
|
||||||
.inputs()
|
.inputs()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| {
|
.enumerate()
|
||||||
|
.map(|(i, ty)| {
|
||||||
Some(match ty.kind {
|
Some(match ty.kind {
|
||||||
ty::Param(param) if param.name == kw::SelfUpper => "self".to_string(),
|
ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
|
||||||
ty::Ref(reg, ref_ty, mutability) => {
|
ty::Ref(reg, ref_ty, mutability) if i == 0 => {
|
||||||
let reg = match &format!("{}", reg)[..] {
|
let reg = match &format!("{}", reg)[..] {
|
||||||
"'_" | "" => String::new(),
|
"'_" | "" => String::new(),
|
||||||
reg => format!("{} ", reg),
|
reg => format!("{} ", reg),
|
||||||
};
|
};
|
||||||
|
if assoc.fn_has_self_parameter {
|
||||||
match ref_ty.kind {
|
match ref_ty.kind {
|
||||||
ty::Param(param) if param.name == kw::SelfUpper => {
|
ty::Param(param) if param.name == kw::SelfUpper => {
|
||||||
format!("&{}{}self", reg, mutability.prefix_str())
|
format!("&{}{}self", reg, mutability.prefix_str())
|
||||||
}
|
}
|
||||||
_ => format!("_: {:?}", ty),
|
|
||||||
|
_ => format!("self: {}", 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 }))
|
.chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
|
||||||
@ -2309,6 +2322,7 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
|||||||
tcx.fn_sig(assoc.def_id).skip_binder(),
|
tcx.fn_sig(assoc.def_id).skip_binder(),
|
||||||
assoc.ident,
|
assoc.ident,
|
||||||
tcx.predicates_of(assoc.def_id),
|
tcx.predicates_of(assoc.def_id),
|
||||||
|
assoc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
|
ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
|
||||||
|
@ -2,4 +2,8 @@ pub trait X {
|
|||||||
const CONSTANT: u32;
|
const CONSTANT: u32;
|
||||||
type Type;
|
type Type;
|
||||||
fn method(&self, s: String) -> Self::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;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
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
|
--> $DIR/m2.rs:9:1
|
||||||
|
|
|
|
||||||
LL | impl m1::X for X {
|
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: `const CONSTANT: u32 = 42;`
|
||||||
= help: implement the missing item: `type Type = Type;`
|
= 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 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user