about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-01-22 05:42:11 +0000
committerbors <bors@rust-lang.org>2019-01-22 05:42:11 +0000
commit8e9774ffcf892c85d2e29030c17af1c246e6aa73 (patch)
tree38724b06007cd3fa373607c8b4044d9df5329fa4
parent51cc3cdcf060c1bf3e4d45947f7a6bc20f9960f7 (diff)
parente195ce654a570606a85ead6cefb36042a206205a (diff)
downloadrust-8e9774ffcf892c85d2e29030c17af1c246e6aa73.tar.gz
rust-8e9774ffcf892c85d2e29030c17af1c246e6aa73.zip
Auto merge of #57475 - SimonSapin:signed, r=estebank
Add signed num::NonZeroI* types

Multiple people have asked for them in https://github.com/rust-lang/rust/issues/49137. Given that the unsigned ones already exist, they are very easy to add and not an additional maintenance burden.
-rw-r--r--src/libcore/num/mod.rs36
-rw-r--r--src/libcore/tests/nonzero.rs10
-rw-r--r--src/librustc/traits/error_reporting.rs10
-rw-r--r--src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr4
-rw-r--r--src/test/ui/try-block/try-block-bad-type.stderr4
6 files changed, 42 insertions, 24 deletions
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 6827364c0f8..41caa1788fb 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -10,9 +10,9 @@ use ops;
 use str::FromStr;
 
 macro_rules! impl_nonzero_fmt {
-    ( ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
+    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
         $(
-            #[stable(feature = "nonzero", since = "1.28.0")]
+            #[$stability]
             impl fmt::$Trait for $Ty {
                 #[inline]
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -31,7 +31,7 @@ macro_rules! doc_comment {
 }
 
 macro_rules! nonzero_integers {
-    ( $( $Ty: ident($Int: ty); )+ ) => {
+    ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
         $(
             doc_comment! {
                 concat!("An integer that is known not to equal zero.
@@ -41,10 +41,10 @@ For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!(
 
 ```rust
 use std::mem::size_of;
-assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
+assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
 ">());
 ```"),
-                #[stable(feature = "nonzero", since = "1.28.0")]
+                #[$stability]
                 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
                 #[repr(transparent)]
                 #[rustc_layout_scalar_valid_range_start(1)]
@@ -57,14 +57,14 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st
                 /// # Safety
                 ///
                 /// The value must not be zero.
-                #[stable(feature = "nonzero", since = "1.28.0")]
+                #[$stability]
                 #[inline]
                 pub const unsafe fn new_unchecked(n: $Int) -> Self {
                     $Ty(n)
                 }
 
                 /// Create a non-zero if the given value is not zero.
-                #[stable(feature = "nonzero", since = "1.28.0")]
+                #[$stability]
                 #[inline]
                 pub fn new(n: $Int) -> Option<Self> {
                     if n != 0 {
@@ -75,7 +75,7 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st
                 }
 
                 /// Returns the value as a primitive type.
-                #[stable(feature = "nonzero", since = "1.28.0")]
+                #[$stability]
                 #[inline]
                 pub const fn get(self) -> $Int {
                     self.0
@@ -91,19 +91,25 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st
             }
 
             impl_nonzero_fmt! {
-                (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
+                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
             }
         )+
     }
 }
 
 nonzero_integers! {
-    NonZeroU8(u8);
-    NonZeroU16(u16);
-    NonZeroU32(u32);
-    NonZeroU64(u64);
-    NonZeroU128(u128);
-    NonZeroUsize(usize);
+    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
+    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
+    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
+    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
+    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
+    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
+    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
+    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
+    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
+    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
+    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
+    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
 }
 
 /// Provides intentionally-wrapped arithmetic on `T`.
diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs
index c813bf20cb6..4532568ee0c 100644
--- a/src/libcore/tests/nonzero.rs
+++ b/src/libcore/tests/nonzero.rs
@@ -1,4 +1,4 @@
-use core::num::NonZeroU32;
+use core::num::{NonZeroU32, NonZeroI32};
 use core::option::Option;
 use core::option::Option::{Some, None};
 use std::mem::size_of;
@@ -13,6 +13,7 @@ fn test_create_nonzero_instance() {
 #[test]
 fn test_size_nonzero_in_option() {
     assert_eq!(size_of::<NonZeroU32>(), size_of::<Option<NonZeroU32>>());
+    assert_eq!(size_of::<NonZeroI32>(), size_of::<Option<NonZeroI32>>());
 }
 
 #[test]
@@ -118,3 +119,10 @@ fn test_from_nonzero() {
     let num: u32 = nz.into();
     assert_eq!(num, 1u32);
 }
+
+#[test]
+fn test_from_signed_nonzero() {
+    let nz = NonZeroI32::new(1).unwrap();
+    let num: i32 = nz.into();
+    assert_eq!(num, 1i32);
+}
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 367a7eacdfc..1c92e2da588 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -471,7 +471,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 
     fn report_similar_impl_candidates(&self,
-                                      mut impl_candidates: Vec<ty::TraitRef<'tcx>>,
+                                      impl_candidates: Vec<ty::TraitRef<'tcx>>,
                                       err: &mut DiagnosticBuilder<'_>)
     {
         if impl_candidates.is_empty() {
@@ -497,14 +497,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         });
 
         // Sort impl candidates so that ordering is consistent for UI tests.
-        let normalized_impl_candidates = &mut impl_candidates[0..end]
+        let mut normalized_impl_candidates = impl_candidates
             .iter()
             .map(normalize)
             .collect::<Vec<String>>();
+
+        // Sort before taking the `..end` range,
+        // because the ordering of `impl_candidates` may not be deterministic:
+        // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507
         normalized_impl_candidates.sort();
 
         err.help(&format!("the following implementations were found:{}{}",
-                          normalized_impl_candidates.join(""),
+                          normalized_impl_candidates[..end].join(""),
                           if len > 5 {
                               format!("\nand {} others", len - 4)
                           } else {
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
index 140f98b4038..d6d5ce4d1a7 100644
--- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
@@ -8,7 +8,7 @@ LL |     f1.foo(1usize);
              <Bar as Foo<i16>>
              <Bar as Foo<i32>>
              <Bar as Foo<i8>>
-             <Bar as Foo<u8>>
+             <Bar as Foo<u16>>
            and 2 others
 
 error: aborting due to previous error
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index 23466980f92..3411958be62 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -40,10 +40,10 @@ LL |     Foo::<i32>::bar(&true); //~ ERROR is not satisfied
    |     ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `bool`
    |
    = help: the following implementations were found:
+             <bool as Foo<bool>>
+             <bool as Foo<i8>>
              <bool as Foo<u16>>
              <bool as Foo<u32>>
-             <bool as Foo<u64>>
-             <bool as Foo<u8>>
            and 2 others
 note: required by `Foo::bar`
   --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr
index 202885e383e..df8e646280c 100644
--- a/src/test/ui/try-block/try-block-bad-type.stderr
+++ b/src/test/ui/try-block/try-block-bad-type.stderr
@@ -6,10 +6,10 @@ LL |         Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>`
    |
    = help: the following implementations were found:
              <i32 as std::convert::From<bool>>
+             <i32 as std::convert::From<core::num::NonZeroI32>>
              <i32 as std::convert::From<i16>>
              <i32 as std::convert::From<i8>>
-             <i32 as std::convert::From<u16>>
-             <i32 as std::convert::From<u8>>
+           and 2 others
    = note: required by `std::convert::From::from`
 
 error[E0271]: type mismatch resolving `<std::result::Result<i32, i32> as std::ops::Try>::Ok == &str`