Skip to content

Commit

Permalink
Merge pull request #1302 from dtolnay/never
Browse files Browse the repository at this point in the history
Implement traits for `!`
  • Loading branch information
dtolnay authored Jun 3, 2018
2 parents 0a71fe3 + 22b1af7 commit bd366f6
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 1 deletion.
10 changes: 10 additions & 0 deletions serde/src/de/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ impl<'de> Deserialize<'de> for () {
}
}

#[cfg(feature = "unstable")]
impl<'de> Deserialize<'de> for ! {
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Err(Error::custom("cannot deserialize `!`"))
}
}

////////////////////////////////////////////////////////////////////////////////

struct BoolVisitor;
Expand Down
1 change: 1 addition & 0 deletions serde/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
//! - PathBuf
//! - Range\<T\>
//! - num::NonZero*
//! - `!` *(unstable)*
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
Expand Down
42 changes: 42 additions & 0 deletions serde/src/de/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,48 @@ where

////////////////////////////////////////////////////////////////////////////////

/// A deserializer that cannot be instantiated.
#[cfg(feature = "unstable")]
pub struct NeverDeserializer<E> {
never: !,
marker: PhantomData<E>,
}

#[cfg(feature = "unstable")]
impl<'de, E> IntoDeserializer<'de, E> for !
where
E: de::Error,
{
type Deserializer = NeverDeserializer<E>;

fn into_deserializer(self) -> Self::Deserializer {
self
}
}

#[cfg(feature = "unstable")]
impl<'de, E> de::Deserializer<'de> for NeverDeserializer<E>
where
E: de::Error,
{
type Error = E;

fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.never
}

forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}

////////////////////////////////////////////////////////////////////////////////

macro_rules! primitive_deserializer {
($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => {
#[doc = "A deserializer holding"]
Expand Down
2 changes: 1 addition & 1 deletion serde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
// discussion of these features please refer to this issue:
//
// https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization))]
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
Expand Down
10 changes: 10 additions & 0 deletions serde/src/ser/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,16 @@ impl Serialize for () {
}
}

#[cfg(feature = "unstable")]
impl Serialize for ! {
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
*self
}
}

////////////////////////////////////////////////////////////////////////////////

macro_rules! tuple_impls {
Expand Down
1 change: 1 addition & 0 deletions serde/src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
//! - PathBuf
//! - Range\<T\>
//! - num::NonZero*
//! - `!` *(unstable)*
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
Expand Down
25 changes: 25 additions & 0 deletions test_suite/tests/test_de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// except according to those terms.

#![cfg_attr(feature = "cargo-clippy", allow(decimal_literal_representation))]
#![cfg_attr(feature = "unstable", feature(never_type))]

#[macro_use]
extern crate serde_derive;
Expand Down Expand Up @@ -984,6 +985,16 @@ declare_tests! {
}
}

#[cfg(feature = "unstable")]
declare_tests! {
test_never_result {
Ok::<u8, !>(0) => &[
Token::NewtypeVariant { name: "Result", variant: "Ok" },
Token::U8(0),
],
}
}

#[cfg(unix)]
#[test]
fn test_osstring() {
Expand Down Expand Up @@ -1051,6 +1062,20 @@ fn test_cstr_internal_null_end() {
);
}

#[cfg(feature = "unstable")]
#[test]
fn test_never_type() {
assert_de_tokens_error::<!>(&[], "cannot deserialize `!`");

assert_de_tokens_error::<Result<u8, !>>(
&[Token::NewtypeVariant {
name: "Result",
variant: "Err",
}],
"cannot deserialize `!`",
);
}

declare_error_tests! {
test_unknown_field<StructDenyUnknown> {
&[
Expand Down
12 changes: 12 additions & 0 deletions test_suite/tests/test_ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(feature = "unstable", feature(never_type))]

#[macro_use]
extern crate serde_derive;

Expand Down Expand Up @@ -548,6 +550,16 @@ declare_tests! {
}
}

#[cfg(feature = "unstable")]
declare_tests! {
test_never_result {
Ok::<u8, !>(0) => &[
Token::NewtypeVariant { name: "Result", variant: "Ok" },
Token::U8(0),
],
}
}

#[test]
#[cfg(unix)]
fn test_cannot_serialize_paths() {
Expand Down

0 comments on commit bd366f6

Please sign in to comment.