Merge pull request #1302 from dtolnay/never

Implement traits for `!`
This commit is contained in:
David Tolnay 2018-06-03 00:30:19 -07:00 committed by GitHub
commit bd366f675e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 102 additions and 1 deletions

View File

@ -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;

View File

@ -98,6 +98,7 @@
//! - PathBuf
//! - Range\<T\>
//! - num::NonZero*
//! - `!` *(unstable)*
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr

View File

@ -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"]

View File

@ -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

View File

@ -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 {

View File

@ -93,6 +93,7 @@
//! - PathBuf
//! - Range\<T\>
//! - num::NonZero*
//! - `!` *(unstable)*
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr

View File

@ -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;
@ -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() {
@ -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> {
&[

View File

@ -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;
@ -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() {