diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs
index d7c57568..c5aaca72 100644
--- a/serde/src/de/impls.rs
+++ b/serde/src/de/impls.rs
@@ -81,8 +81,34 @@ impl<'de> Deserialize<'de> for bool {
 ////////////////////////////////////////////////////////////////////////////////
 
 macro_rules! impl_deserialize_num {
-    ($ty:ident, $deserialize:ident $($methods:tt)*) => {
-        impl<'de> Deserialize<'de> for $ty {
+    ($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
+        impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*);
+
+        #[cfg(all(not(no_num_nonzero), $($($cfg)*)*))]
+        impl<'de> Deserialize<'de> for num::$nonzero {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                struct NonZeroVisitor;
+
+                impl<'de> Visitor<'de> for NonZeroVisitor {
+                    type Value = num::$nonzero;
+
+                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                        formatter.write_str(concat!("a nonzero ", stringify!($primitive)))
+                    }
+
+                    $($($method!(nonzero $primitive $val : $visit);)*)*
+                }
+
+                deserializer.$deserialize(NonZeroVisitor)
+            }
+        }
+    };
+
+    ($primitive:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
+        impl<'de> Deserialize<'de> for $primitive {
             #[inline]
             fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
             where
@@ -91,13 +117,13 @@ macro_rules! impl_deserialize_num {
                 struct PrimitiveVisitor;
 
                 impl<'de> Visitor<'de> for PrimitiveVisitor {
-                    type Value = $ty;
+                    type Value = $primitive;
 
                     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-                        formatter.write_str(stringify!($ty))
+                        formatter.write_str(stringify!($primitive))
                     }
 
-                    $($methods)*
+                    $($($method!($val : $visit);)*)*
                 }
 
                 deserializer.$deserialize(PrimitiveVisitor)
@@ -116,85 +142,149 @@ macro_rules! num_self {
             Ok(v)
         }
     };
+
+    (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            if let Some(nonzero) = Self::Value::new(v) {
+                Ok(nonzero)
+            } else {
+                Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
+            }
+        }
+    };
 }
 
 macro_rules! num_as_self {
-    ($($ty:ident : $visit:ident)*) => {
-        $(
-            #[inline]
-            fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
-            where
-                E: Error,
-            {
-                Ok(v as Self::Value)
+    ($ty:ident : $visit:ident) => {
+        #[inline]
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            Ok(v as Self::Value)
+        }
+    };
+
+    (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            if let Some(nonzero) = Self::Value::new(v as $primitive) {
+                Ok(nonzero)
+            } else {
+                Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
             }
-        )*
+        }
     };
 }
 
 macro_rules! int_to_int {
-    ($($ty:ident : $visit:ident)*) => {
-        $(
-            #[inline]
-            fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
-            where
-                E: Error,
+    ($ty:ident : $visit:ident) => {
+        #[inline]
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            if Self::Value::min_value() as i64 <= v as i64
+                && v as i64 <= Self::Value::max_value() as i64
             {
-                if Self::Value::min_value() as i64 <= v as i64 && v as i64 <= Self::Value::max_value() as i64 {
-                    Ok(v as Self::Value)
-                } else {
-                    Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+                Ok(v as Self::Value)
+            } else {
+                Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+            }
+        }
+    };
+
+    (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            if $primitive::min_value() as i64 <= v as i64
+                && v as i64 <= $primitive::max_value() as i64
+            {
+                if let Some(nonzero) = Self::Value::new(v as $primitive) {
+                    return Ok(nonzero);
                 }
             }
-        )*
+            Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+        }
     };
 }
 
 macro_rules! int_to_uint {
-    ($($ty:ident : $visit:ident)*) => {
-        $(
-            #[inline]
-            fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
-            where
-                E: Error,
-            {
-                if 0 <= v && v as u64 <= Self::Value::max_value() as u64 {
-                    Ok(v as Self::Value)
-                } else {
-                    Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+    ($ty:ident : $visit:ident) => {
+        #[inline]
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            if 0 <= v && v as u64 <= Self::Value::max_value() as u64 {
+                Ok(v as Self::Value)
+            } else {
+                Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+            }
+        }
+    };
+
+    (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            if 0 < v && v as u64 <= $primitive::max_value() as u64 {
+                if let Some(nonzero) = Self::Value::new(v as $primitive) {
+                    return Ok(nonzero);
                 }
             }
-        )*
+            Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+        }
     };
 }
 
 macro_rules! uint_to_self {
-    ($($ty:ident : $visit:ident)*) => {
-        $(
-            #[inline]
-            fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
-            where
-                E: Error,
-            {
-                if v as u64 <= Self::Value::max_value() as u64 {
-                    Ok(v as Self::Value)
-                } else {
-                    Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
+    ($ty:ident : $visit:ident) => {
+        #[inline]
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            if v as u64 <= Self::Value::max_value() as u64 {
+                Ok(v as Self::Value)
+            } else {
+                Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
+            }
+        }
+    };
+
+    (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+        fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+        where
+            E: Error,
+        {
+            if v as u64 <= $primitive::max_value() as u64 {
+                if let Some(nonzero) = Self::Value::new(v as $primitive) {
+                    return Ok(nonzero);
                 }
             }
-        )*
+            Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
+        }
     };
 }
 
 impl_deserialize_num! {
-    i8, deserialize_i8
+    i8, NonZeroI8 cfg(not(no_num_nonzero_signed)), deserialize_i8
     num_self!(i8:visit_i8);
     int_to_int!(i16:visit_i16 i32:visit_i32 i64:visit_i64);
     uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
 }
 
 impl_deserialize_num! {
-    i16, deserialize_i16
+    i16, NonZeroI16 cfg(not(no_num_nonzero_signed)), deserialize_i16
     num_self!(i16:visit_i16);
     num_as_self!(i8:visit_i8);
     int_to_int!(i32:visit_i32 i64:visit_i64);
@@ -202,7 +292,7 @@ impl_deserialize_num! {
 }
 
 impl_deserialize_num! {
-    i32, deserialize_i32
+    i32, NonZeroI32 cfg(not(no_num_nonzero_signed)), deserialize_i32
     num_self!(i32:visit_i32);
     num_as_self!(i8:visit_i8 i16:visit_i16);
     int_to_int!(i64:visit_i64);
@@ -210,28 +300,28 @@ impl_deserialize_num! {
 }
 
 impl_deserialize_num! {
-    i64, deserialize_i64
+    i64, NonZeroI64 cfg(not(no_num_nonzero_signed)), deserialize_i64
     num_self!(i64:visit_i64);
     num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32);
     uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
 }
 
 impl_deserialize_num! {
-    isize, deserialize_i64
+    isize, NonZeroIsize cfg(not(no_num_nonzero_signed)), deserialize_i64
     num_as_self!(i8:visit_i8 i16:visit_i16);
     int_to_int!(i32:visit_i32 i64:visit_i64);
     uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
 }
 
 impl_deserialize_num! {
-    u8, deserialize_u8
+    u8, NonZeroU8, deserialize_u8
     num_self!(u8:visit_u8);
     int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
     uint_to_self!(u16:visit_u16 u32:visit_u32 u64:visit_u64);
 }
 
 impl_deserialize_num! {
-    u16, deserialize_u16
+    u16, NonZeroU16, deserialize_u16
     num_self!(u16:visit_u16);
     num_as_self!(u8:visit_u8);
     int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
@@ -239,7 +329,7 @@ impl_deserialize_num! {
 }
 
 impl_deserialize_num! {
-    u32, deserialize_u32
+    u32, NonZeroU32, deserialize_u32
     num_self!(u32:visit_u32);
     num_as_self!(u8:visit_u8 u16:visit_u16);
     int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
@@ -247,14 +337,14 @@ impl_deserialize_num! {
 }
 
 impl_deserialize_num! {
-    u64, deserialize_u64
+    u64, NonZeroU64, deserialize_u64
     num_self!(u64:visit_u64);
     num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32);
     int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
 }
 
 impl_deserialize_num! {
-    usize, deserialize_u64
+    usize, NonZeroUsize, deserialize_u64
     num_as_self!(u8:visit_u8 u16:visit_u16);
     int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
     uint_to_self!(u32:visit_u32 u64:visit_u64);
@@ -277,42 +367,62 @@ impl_deserialize_num! {
 }
 
 serde_if_integer128! {
-    impl_deserialize_num! {
-        i128, deserialize_i128
-        num_self!(i128:visit_i128);
-        num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
-        num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
-
-        #[inline]
-        fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
-        where
-            E: Error,
-        {
-            if v <= i128::max_value() as u128 {
-                Ok(v as i128)
-            } else {
-                Err(Error::invalid_value(Unexpected::Other("u128"), &self))
+    macro_rules! num_128 {
+        ($ty:ident : $visit:ident) => {
+            fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+            where
+                E: Error,
+            {
+                if v as i128 >= Self::Value::min_value() as i128
+                    && v as u128 <= Self::Value::max_value() as u128
+                {
+                    Ok(v as Self::Value)
+                } else {
+                    Err(Error::invalid_value(
+                        Unexpected::Other(stringify!($ty)),
+                        &self,
+                    ))
+                }
             }
-        }
+        };
+
+        (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+            fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+            where
+                E: Error,
+            {
+                if v as i128 >= $primitive::min_value() as i128
+                    && v as u128 <= $primitive::max_value() as u128
+                {
+                    if let Some(nonzero) = Self::Value::new(v as $primitive) {
+                        Ok(nonzero)
+                    } else {
+                        Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
+                    }
+                } else {
+                    Err(Error::invalid_value(
+                        Unexpected::Other(stringify!($ty)),
+                        &self,
+                    ))
+                }
+            }
+        };
     }
 
     impl_deserialize_num! {
-        u128, deserialize_u128
+        i128, NonZeroI128 cfg(not(no_num_nonzero_signed)), deserialize_i128
+        num_self!(i128:visit_i128);
+        num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+        num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+        num_128!(u128:visit_u128);
+    }
+
+    impl_deserialize_num! {
+        u128, NonZeroU128, deserialize_u128
         num_self!(u128:visit_u128);
         num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
         int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
-
-        #[inline]
-        fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
-        where
-            E: Error,
-        {
-            if 0 <= v {
-                Ok(v as u128)
-            } else {
-                Err(Error::invalid_value(Unexpected::Other("i128"), &self))
-            }
-        }
+        num_128!(i128:visit_i128);
     }
 }
 
@@ -2431,58 +2541,6 @@ where
 
 ////////////////////////////////////////////////////////////////////////////////
 
-macro_rules! nonzero_integers {
-    ( $( $T: ident, )+ ) => {
-        $(
-            #[cfg(not(no_num_nonzero))]
-            impl<'de> Deserialize<'de> for num::$T {
-                fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-                where
-                    D: Deserializer<'de>,
-                {
-                    let value = try!(Deserialize::deserialize(deserializer));
-                    match <num::$T>::new(value) {
-                        Some(nonzero) => Ok(nonzero),
-                        None => Err(Error::custom("expected a non-zero value")),
-                    }
-                }
-            }
-        )+
-    };
-}
-
-nonzero_integers! {
-    NonZeroU8,
-    NonZeroU16,
-    NonZeroU32,
-    NonZeroU64,
-    NonZeroUsize,
-}
-
-#[cfg(not(no_num_nonzero_signed))]
-nonzero_integers! {
-    NonZeroI8,
-    NonZeroI16,
-    NonZeroI32,
-    NonZeroI64,
-    NonZeroIsize,
-}
-
-// Currently 128-bit integers do not work on Emscripten targets so we need an
-// additional `#[cfg]`
-serde_if_integer128! {
-    nonzero_integers! {
-        NonZeroU128,
-    }
-
-    #[cfg(not(no_num_nonzero_signed))]
-    nonzero_integers! {
-        NonZeroI128,
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 impl<'de, T, E> Deserialize<'de> for Result<T, E>
 where
     T: Deserialize<'de>,
diff --git a/test_suite/tests/test_de_error.rs b/test_suite/tests/test_de_error.rs
index da6e7656..db534e98 100644
--- a/test_suite/tests/test_de_error.rs
+++ b/test_suite/tests/test_de_error.rs
@@ -379,57 +379,81 @@ fn test_nonzero_i8() {
     let test = assert_de_tokens_error::<NonZeroI8>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero i8",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero i8",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero i8",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero i8",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero i8",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero i8",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero i8",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero i8",
+    );
 
     // from signed
     test(
         &[Token::I16(-129)],
-        "invalid value: integer `-129`, expected i8",
+        "invalid value: integer `-129`, expected a nonzero i8",
     );
     test(
         &[Token::I32(-129)],
-        "invalid value: integer `-129`, expected i8",
+        "invalid value: integer `-129`, expected a nonzero i8",
     );
     test(
         &[Token::I64(-129)],
-        "invalid value: integer `-129`, expected i8",
+        "invalid value: integer `-129`, expected a nonzero i8",
     );
     test(
         &[Token::I16(128)],
-        "invalid value: integer `128`, expected i8",
+        "invalid value: integer `128`, expected a nonzero i8",
     );
     test(
         &[Token::I32(128)],
-        "invalid value: integer `128`, expected i8",
+        "invalid value: integer `128`, expected a nonzero i8",
     );
     test(
         &[Token::I64(128)],
-        "invalid value: integer `128`, expected i8",
+        "invalid value: integer `128`, expected a nonzero i8",
     );
 
     // from unsigned
     test(
         &[Token::U8(128)],
-        "invalid value: integer `128`, expected i8",
+        "invalid value: integer `128`, expected a nonzero i8",
     );
     test(
         &[Token::U16(128)],
-        "invalid value: integer `128`, expected i8",
+        "invalid value: integer `128`, expected a nonzero i8",
     );
     test(
         &[Token::U32(128)],
-        "invalid value: integer `128`, expected i8",
+        "invalid value: integer `128`, expected a nonzero i8",
     );
     test(
         &[Token::U64(128)],
-        "invalid value: integer `128`, expected i8",
+        "invalid value: integer `128`, expected a nonzero i8",
     );
 }
 
@@ -438,45 +462,69 @@ fn test_nonzero_i16() {
     let test = assert_de_tokens_error::<NonZeroI16>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero i16",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero i16",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero i16",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero i16",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero i16",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero i16",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero i16",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero i16",
+    );
 
     // from signed
     test(
         &[Token::I32(-32769)],
-        "invalid value: integer `-32769`, expected i16",
+        "invalid value: integer `-32769`, expected a nonzero i16",
     );
     test(
         &[Token::I64(-32769)],
-        "invalid value: integer `-32769`, expected i16",
+        "invalid value: integer `-32769`, expected a nonzero i16",
     );
     test(
         &[Token::I32(32768)],
-        "invalid value: integer `32768`, expected i16",
+        "invalid value: integer `32768`, expected a nonzero i16",
     );
     test(
         &[Token::I64(32768)],
-        "invalid value: integer `32768`, expected i16",
+        "invalid value: integer `32768`, expected a nonzero i16",
     );
 
     // from unsigned
     test(
         &[Token::U16(32768)],
-        "invalid value: integer `32768`, expected i16",
+        "invalid value: integer `32768`, expected a nonzero i16",
     );
     test(
         &[Token::U32(32768)],
-        "invalid value: integer `32768`, expected i16",
+        "invalid value: integer `32768`, expected a nonzero i16",
     );
     test(
         &[Token::U64(32768)],
-        "invalid value: integer `32768`, expected i16",
+        "invalid value: integer `32768`, expected a nonzero i16",
     );
 }
 
@@ -485,33 +533,57 @@ fn test_nonzero_i32() {
     let test = assert_de_tokens_error::<NonZeroI32>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero i32",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero i32",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero i32",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero i32",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero i32",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero i32",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero i32",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero i32",
+    );
 
     // from signed
     test(
         &[Token::I64(-2147483649)],
-        "invalid value: integer `-2147483649`, expected i32",
+        "invalid value: integer `-2147483649`, expected a nonzero i32",
     );
     test(
         &[Token::I64(2147483648)],
-        "invalid value: integer `2147483648`, expected i32",
+        "invalid value: integer `2147483648`, expected a nonzero i32",
     );
 
     // from unsigned
     test(
         &[Token::U32(2147483648)],
-        "invalid value: integer `2147483648`, expected i32",
+        "invalid value: integer `2147483648`, expected a nonzero i32",
     );
     test(
         &[Token::U64(2147483648)],
-        "invalid value: integer `2147483648`, expected i32",
+        "invalid value: integer `2147483648`, expected a nonzero i32",
     );
 }
 
@@ -520,19 +592,43 @@ fn test_nonzero_i64() {
     let test = assert_de_tokens_error::<NonZeroI64>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero i64",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero i64",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero i64",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero i64",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero i64",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero i64",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero i64",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero i64",
+    );
 
     // from unsigned
     test(
         &[Token::U64(9223372036854775808)],
-        "invalid value: integer `9223372036854775808`, expected i64",
+        "invalid value: integer `9223372036854775808`, expected a nonzero i64",
     );
 }
 
@@ -541,14 +637,38 @@ fn test_nonzero_i128() {
     let test = assert_de_tokens_error::<NonZeroI128>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero i128",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero i128",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero i128",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero i128",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero i128",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero i128",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero i128",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero i128",
+    );
 }
 
 #[test]
@@ -556,14 +676,38 @@ fn test_nonzero_isize() {
     let test = assert_de_tokens_error::<NonZeroIsize>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero isize",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero isize",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero isize",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero isize",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero isize",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero isize",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero isize",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero isize",
+    );
 }
 
 #[test]
@@ -571,54 +715,81 @@ fn test_nonzero_u8() {
     let test = assert_de_tokens_error::<NonZeroU8>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero u8",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero u8",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero u8",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero u8",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero u8",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero u8",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero u8",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero u8",
+    );
 
     // from signed
-    test(&[Token::I8(-1)], "invalid value: integer `-1`, expected u8");
+    test(
+        &[Token::I8(-1)],
+        "invalid value: integer `-1`, expected a nonzero u8",
+    );
     test(
         &[Token::I16(-1)],
-        "invalid value: integer `-1`, expected u8",
+        "invalid value: integer `-1`, expected a nonzero u8",
     );
     test(
         &[Token::I32(-1)],
-        "invalid value: integer `-1`, expected u8",
+        "invalid value: integer `-1`, expected a nonzero u8",
     );
     test(
         &[Token::I64(-1)],
-        "invalid value: integer `-1`, expected u8",
+        "invalid value: integer `-1`, expected a nonzero u8",
     );
     test(
         &[Token::I16(256)],
-        "invalid value: integer `256`, expected u8",
+        "invalid value: integer `256`, expected a nonzero u8",
     );
     test(
         &[Token::I32(256)],
-        "invalid value: integer `256`, expected u8",
+        "invalid value: integer `256`, expected a nonzero u8",
     );
     test(
         &[Token::I64(256)],
-        "invalid value: integer `256`, expected u8",
+        "invalid value: integer `256`, expected a nonzero u8",
     );
 
     // from unsigned
     test(
         &[Token::U16(256)],
-        "invalid value: integer `256`, expected u8",
+        "invalid value: integer `256`, expected a nonzero u8",
     );
     test(
         &[Token::U32(256)],
-        "invalid value: integer `256`, expected u8",
+        "invalid value: integer `256`, expected a nonzero u8",
     );
     test(
         &[Token::U64(256)],
-        "invalid value: integer `256`, expected u8",
+        "invalid value: integer `256`, expected a nonzero u8",
     );
 }
 
@@ -627,49 +798,73 @@ fn test_nonzero_u16() {
     let test = assert_de_tokens_error::<NonZeroU16>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero u16",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero u16",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero u16",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero u16",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero u16",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero u16",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero u16",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero u16",
+    );
 
     // from signed
     test(
         &[Token::I8(-1)],
-        "invalid value: integer `-1`, expected u16",
+        "invalid value: integer `-1`, expected a nonzero u16",
     );
     test(
         &[Token::I16(-1)],
-        "invalid value: integer `-1`, expected u16",
+        "invalid value: integer `-1`, expected a nonzero u16",
     );
     test(
         &[Token::I32(-1)],
-        "invalid value: integer `-1`, expected u16",
+        "invalid value: integer `-1`, expected a nonzero u16",
     );
     test(
         &[Token::I64(-1)],
-        "invalid value: integer `-1`, expected u16",
+        "invalid value: integer `-1`, expected a nonzero u16",
     );
     test(
         &[Token::I32(65536)],
-        "invalid value: integer `65536`, expected u16",
+        "invalid value: integer `65536`, expected a nonzero u16",
     );
     test(
         &[Token::I64(65536)],
-        "invalid value: integer `65536`, expected u16",
+        "invalid value: integer `65536`, expected a nonzero u16",
     );
 
     // from unsigned
     test(
         &[Token::U32(65536)],
-        "invalid value: integer `65536`, expected u16",
+        "invalid value: integer `65536`, expected a nonzero u16",
     );
     test(
         &[Token::U64(65536)],
-        "invalid value: integer `65536`, expected u16",
+        "invalid value: integer `65536`, expected a nonzero u16",
     );
 }
 
@@ -678,41 +873,65 @@ fn test_nonzero_u32() {
     let test = assert_de_tokens_error::<NonZeroU32>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero u32",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero u32",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero u32",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero u32",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero u32",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero u32",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero u32",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero u32",
+    );
 
     // from signed
     test(
         &[Token::I8(-1)],
-        "invalid value: integer `-1`, expected u32",
+        "invalid value: integer `-1`, expected a nonzero u32",
     );
     test(
         &[Token::I16(-1)],
-        "invalid value: integer `-1`, expected u32",
+        "invalid value: integer `-1`, expected a nonzero u32",
     );
     test(
         &[Token::I32(-1)],
-        "invalid value: integer `-1`, expected u32",
+        "invalid value: integer `-1`, expected a nonzero u32",
     );
     test(
         &[Token::I64(-1)],
-        "invalid value: integer `-1`, expected u32",
+        "invalid value: integer `-1`, expected a nonzero u32",
     );
     test(
         &[Token::I64(4294967296)],
-        "invalid value: integer `4294967296`, expected u32",
+        "invalid value: integer `4294967296`, expected a nonzero u32",
     );
 
     // from unsigned
     test(
         &[Token::U64(4294967296)],
-        "invalid value: integer `4294967296`, expected u32",
+        "invalid value: integer `4294967296`, expected a nonzero u32",
     );
 }
 
@@ -721,31 +940,55 @@ fn test_nonzero_u64() {
     let test = assert_de_tokens_error::<NonZeroU64>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero u64",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero u64",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero u64",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero u64",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero u64",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero u64",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero u64",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero u64",
+    );
 
     // from signed
     test(
         &[Token::I8(-1)],
-        "invalid value: integer `-1`, expected u64",
+        "invalid value: integer `-1`, expected a nonzero u64",
     );
     test(
         &[Token::I16(-1)],
-        "invalid value: integer `-1`, expected u64",
+        "invalid value: integer `-1`, expected a nonzero u64",
     );
     test(
         &[Token::I32(-1)],
-        "invalid value: integer `-1`, expected u64",
+        "invalid value: integer `-1`, expected a nonzero u64",
     );
     test(
         &[Token::I64(-1)],
-        "invalid value: integer `-1`, expected u64",
+        "invalid value: integer `-1`, expected a nonzero u64",
     );
 }
 
@@ -754,31 +997,55 @@ fn test_nonzero_u128() {
     let test = assert_de_tokens_error::<NonZeroU128>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero u128",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero u128",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero u128",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero u128",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero u128",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero u128",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero u128",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero u128",
+    );
 
     // from signed
     test(
         &[Token::I8(-1)],
-        "invalid value: integer `-1`, expected u128",
+        "invalid value: integer `-1`, expected a nonzero u128",
     );
     test(
         &[Token::I16(-1)],
-        "invalid value: integer `-1`, expected u128",
+        "invalid value: integer `-1`, expected a nonzero u128",
     );
     test(
         &[Token::I32(-1)],
-        "invalid value: integer `-1`, expected u128",
+        "invalid value: integer `-1`, expected a nonzero u128",
     );
     test(
         &[Token::I64(-1)],
-        "invalid value: integer `-1`, expected u128",
+        "invalid value: integer `-1`, expected a nonzero u128",
     );
 }
 
@@ -787,31 +1054,55 @@ fn test_nonzero_usize() {
     let test = assert_de_tokens_error::<NonZeroUsize>;
 
     // from zero
-    test(&[Token::I8(0)], "expected a non-zero value");
-    test(&[Token::I16(0)], "expected a non-zero value");
-    test(&[Token::I32(0)], "expected a non-zero value");
-    test(&[Token::I64(0)], "expected a non-zero value");
-    test(&[Token::U8(0)], "expected a non-zero value");
-    test(&[Token::U16(0)], "expected a non-zero value");
-    test(&[Token::U32(0)], "expected a non-zero value");
-    test(&[Token::U64(0)], "expected a non-zero value");
+    test(
+        &[Token::I8(0)],
+        "invalid value: integer `0`, expected a nonzero usize",
+    );
+    test(
+        &[Token::I16(0)],
+        "invalid value: integer `0`, expected a nonzero usize",
+    );
+    test(
+        &[Token::I32(0)],
+        "invalid value: integer `0`, expected a nonzero usize",
+    );
+    test(
+        &[Token::I64(0)],
+        "invalid value: integer `0`, expected a nonzero usize",
+    );
+    test(
+        &[Token::U8(0)],
+        "invalid value: integer `0`, expected a nonzero usize",
+    );
+    test(
+        &[Token::U16(0)],
+        "invalid value: integer `0`, expected a nonzero usize",
+    );
+    test(
+        &[Token::U32(0)],
+        "invalid value: integer `0`, expected a nonzero usize",
+    );
+    test(
+        &[Token::U64(0)],
+        "invalid value: integer `0`, expected a nonzero usize",
+    );
 
     // from signed
     test(
         &[Token::I8(-1)],
-        "invalid value: integer `-1`, expected usize",
+        "invalid value: integer `-1`, expected a nonzero usize",
     );
     test(
         &[Token::I16(-1)],
-        "invalid value: integer `-1`, expected usize",
+        "invalid value: integer `-1`, expected a nonzero usize",
     );
     test(
         &[Token::I32(-1)],
-        "invalid value: integer `-1`, expected usize",
+        "invalid value: integer `-1`, expected a nonzero usize",
     );
     test(
         &[Token::I64(-1)],
-        "invalid value: integer `-1`, expected usize",
+        "invalid value: integer `-1`, expected a nonzero usize",
     );
 }