]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #71231 - cuviper:rustc_or_patterns, r=Mark-Simulacrum
authorbors <bors@rust-lang.org>
Sun, 19 Apr 2020 16:43:02 +0000 (16:43 +0000)
committerbors <bors@rust-lang.org>
Sun, 19 Apr 2020 16:43:02 +0000 (16:43 +0000)
Dogfood more or_patterns in the compiler

Another step toward the stabilization of `or_patterns`...

cc #54883 @Centril
r? @Mark-Simulacrum

.github/ISSUE_TEMPLATE/tracking_issue.md
src/liballoc/rc.rs
src/liballoc/sync.rs
src/libcore/intrinsics.rs
src/librustc_error_codes/error_codes/E0522.md
src/librustc_typeck/check/mod.rs
src/test/ui/missing/missing-items/auxiliary/m1.rs
src/test/ui/missing/missing-items/m2.stderr

index 9457cce11afbeb3e16022e552dea673f32c1d974..51bf0c3ee673652e64d8770d189b2454f38277d3 100644 (file)
@@ -1,6 +1,6 @@
 ---
 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
 ---
index abc4056cf5695746d93fa37e992972146ab9781f..e106b4354e4e942e731192ec822834a12bb299f7 100644 (file)
@@ -569,9 +569,33 @@ impl<T: ?Sized> Rc<T> {
     /// ```
     #[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.
@@ -1644,8 +1668,8 @@ pub fn new() -> 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
-    /// 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
     ///
@@ -1658,31 +1682,22 @@ pub fn new() -> Weak<T> {
     /// 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.
@@ -1691,7 +1706,7 @@ pub fn as_raw(&self) -> *const T {
     /// 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
     ///
@@ -1712,10 +1727,10 @@ pub fn as_raw(&self) -> *const T {
     /// ```
     ///
     /// [`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
     }
@@ -1730,9 +1745,8 @@ pub fn into_raw(self) -> *const T {
     ///
     /// # 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
@@ -1765,7 +1779,6 @@ pub fn into_raw(self) -> *const T {
     /// [`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")]
index b1b22e46a7c2fd0766b9e5ee671a9e11d3641010..54df2b60857803541ab7dbb15e13904bcf1a1b76 100644 (file)
@@ -566,9 +566,33 @@ impl<T: ?Sized> Arc<T> {
     /// ```
     #[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.
@@ -1340,8 +1364,8 @@ pub fn new() -> 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
-    /// 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
     ///
@@ -1354,31 +1378,22 @@ pub fn new() -> Weak<T> {
     /// 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.
@@ -1387,7 +1402,7 @@ pub fn as_raw(&self) -> *const T {
     /// 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
     ///
@@ -1408,10 +1423,10 @@ pub fn as_raw(&self) -> *const T {
     /// ```
     ///
     /// [`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
     }
@@ -1427,9 +1442,8 @@ pub fn into_raw(self) -> *const T {
     ///
     /// # 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
@@ -1458,7 +1472,6 @@ pub fn into_raw(self) -> *const T {
     /// 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
index 4a11fb393899f26acccfe05b13f9d23f33c0394e..75c7313089112ca55eed25d8eb3e2f68a85d1c9e 100644 (file)
     /// 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`:
     ///
     /// ```
index e4756c384c495ffc02fc3e0972e7dbed1f47ab69..83272314a87086d7c35bb9823a76d908f9e7487f 100644 (file)
@@ -1,7 +1,5 @@
-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
@@ -12,3 +10,8 @@ fn cookie() -> ! { // error: definition of an unknown language item: `cookie`
     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).
index d75d57b026c9bf8bc5093e3e7ddb18c2286cce5f..1be8d258dcb18d29333f7e2b447c4e51173d485b 100644 (file)
@@ -2253,26 +2253,39 @@ fn fn_sig_suggestion(
     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 }))
@@ -2311,6 +2324,7 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
                 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),
index 7705066760c50f31a98b5785af7a5f4ec270762a..fcf52c9e88743093482a5c5365b1cb158638557e 100644 (file)
@@ -2,4 +2,8 @@ pub trait X {
     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;
 }
index 094782099f6ed6f1159a3fb2ef2723944016492b..64e9530e61348276b9a7bc51ccb76b9d0697bdd4 100644 (file)
@@ -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
    |
 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