blob: c048af8ac91eddb1f8f7da3a7bc66dc57365fdd3 [file] [log] [blame]
use quote::quote;
use syn::Result;
use super::test_derive;
#[test]
fn default_struct() -> Result<()> {
test_derive(
quote! {
#[derive_where(Default; T)]
enum Test<T> {
#[derive_where(default)]
A { field: T },
}
},
quote! {
#[automatically_derived]
impl<T> ::core::default::Default for Test<T>
where T: ::core::default::Default
{
fn default() -> Self {
Test::A { field: ::core::default::Default::default() }
}
}
},
)
}
#[test]
fn default_tuple() -> Result<()> {
test_derive(
quote! {
#[derive_where(Default; T)]
enum Test<T> {
#[derive_where(default)]
A(T),
}
},
quote! {
#[automatically_derived]
impl<T> ::core::default::Default for Test<T>
where T: ::core::default::Default
{
fn default() -> Self {
Test::A(::core::default::Default::default())
}
}
},
)
}
#[test]
fn default_unit() -> Result<()> {
test_derive(
quote! {
#[derive_where(Default; T)]
enum Test<T> {
#[derive_where(default)]
A,
B(T),
}
},
quote! {
#[automatically_derived]
impl<T> ::core::default::Default for Test<T>
where T: ::core::default::Default
{
fn default() -> Self {
Test::A
}
}
},
)
}
#[test]
fn one_data() -> Result<()> {
test_derive(
quote! {
#[derive_where(PartialEq, PartialOrd)]
enum Test<T> {
A(std::marker::PhantomData<T>),
}
},
quote! {
#[automatically_derived]
impl<T> ::core::cmp::PartialEq for Test<T> {
#[inline]
fn eq(&self, __other: &Self) -> bool {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
true && ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
}
}
}
#[automatically_derived]
impl<T> ::core::cmp::PartialOrd for Test<T> {
#[inline]
fn partial_cmp(&self, __other: &Self) -> ::core::option::Option<::core::cmp::Ordering> {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
match ::core::cmp::PartialOrd::partial_cmp(__field_0, __other_field_0) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
__cmp => __cmp,
},
}
}
}
},
)
}
#[test]
fn two_data() -> Result<()> {
#[cfg(not(feature = "safe"))]
let unreachable = quote! { unsafe { ::core::hint::unreachable_unchecked() } };
#[cfg(feature = "safe")]
let unreachable = quote! { ::core::unreachable!("comparing variants yielded unexpected results") };
#[cfg(feature = "nightly")]
let discriminant = quote! {
let __self_disc = ::core::intrinsics::discriminant_value(self);
let __other_disc = ::core::intrinsics::discriminant_value(__other);
};
#[cfg(not(feature = "nightly"))]
let discriminant = quote! {
let __self_disc = ::core::mem::discriminant(self);
let __other_disc = ::core::mem::discriminant(__other);
};
#[cfg(feature = "nightly")]
let partial_ord = quote! {
::core::cmp::PartialOrd::partial_cmp(&__self_disc, &__other_disc)
};
#[cfg(not(feature = "nightly"))]
let partial_ord = quote! {
const fn __discriminant<T>(__this: &Test<T>) -> isize {
match __this {
Test::A(ref __field_0) => 0,
Test::B(ref __field_0) => 1
}
}
::core::cmp::PartialOrd::partial_cmp(&__discriminant(self), &__discriminant(__other))
};
test_derive(
quote! {
#[derive_where(PartialEq, PartialOrd)]
enum Test<T> {
A(std::marker::PhantomData<T>),
B(std::marker::PhantomData<T>),
}
},
quote! {
#[automatically_derived]
impl<T> ::core::cmp::PartialEq for Test<T> {
#[inline]
fn eq(&self, __other: &Self) -> bool {
if ::core::mem::discriminant(self) == ::core::mem::discriminant(__other) {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
true && ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
(Test::B(ref __field_0), Test::B(ref __other_field_0)) =>
true && ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
_ => #unreachable,
}
} else {
false
}
}
}
#[automatically_derived]
impl<T> ::core::cmp::PartialOrd for Test<T> {
#[inline]
fn partial_cmp(&self, __other: &Self) -> ::core::option::Option<::core::cmp::Ordering> {
#discriminant
if __self_disc == __other_disc {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
match ::core::cmp::PartialOrd::partial_cmp(__field_0, __other_field_0) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
__cmp => __cmp,
},
(Test::B(ref __field_0), Test::B(ref __other_field_0)) =>
match ::core::cmp::PartialOrd::partial_cmp(__field_0, __other_field_0) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
__cmp => __cmp,
},
_ => #unreachable,
}
} else {
#partial_ord
}
}
}
},
)
}
#[test]
fn unit() -> Result<()> {
#[cfg(feature = "nightly")]
let discriminant = quote! {
let __self_disc = ::core::intrinsics::discriminant_value(self);
let __other_disc = ::core::intrinsics::discriminant_value(__other);
};
#[cfg(not(feature = "nightly"))]
let discriminant = quote! {
let __self_disc = ::core::mem::discriminant(self);
let __other_disc = ::core::mem::discriminant(__other);
};
#[cfg(feature = "nightly")]
let partial_ord = quote! {
::core::cmp::PartialOrd::partial_cmp(&__self_disc, &__other_disc)
};
#[cfg(not(feature = "nightly"))]
let partial_ord = quote! {
const fn __discriminant<T>(__this: &Test<T>) -> isize {
match __this {
Test::A(ref __field_0) => 0,
Test::B => 1
}
}
::core::cmp::PartialOrd::partial_cmp(&__discriminant(self), &__discriminant(__other))
};
test_derive(
quote! {
#[derive_where(PartialEq, PartialOrd)]
enum Test<T> {
A(std::marker::PhantomData<T>),
B,
}
},
quote! {
#[automatically_derived]
impl<T> ::core::cmp::PartialEq for Test<T> {
#[inline]
fn eq(&self, __other: &Self) -> bool {
if ::core::mem::discriminant(self) == ::core::mem::discriminant(__other) {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
true && ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
_ => true,
}
} else {
false
}
}
}
#[automatically_derived]
impl<T> ::core::cmp::PartialOrd for Test<T> {
#[inline]
fn partial_cmp(&self, __other: &Self) -> ::core::option::Option<::core::cmp::Ordering> {
#discriminant
if __self_disc == __other_disc {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
match ::core::cmp::PartialOrd::partial_cmp(__field_0, __other_field_0) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
__cmp => __cmp,
},
_ => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
}
} else {
#partial_ord
}
}
}
},
)
}
#[test]
fn struct_unit() -> Result<()> {
#[cfg(feature = "nightly")]
let discriminant = quote! {
let __self_disc = ::core::intrinsics::discriminant_value(self);
let __other_disc = ::core::intrinsics::discriminant_value(__other);
};
#[cfg(not(feature = "nightly"))]
let discriminant = quote! {
let __self_disc = ::core::mem::discriminant(self);
let __other_disc = ::core::mem::discriminant(__other);
};
#[cfg(feature = "nightly")]
let partial_ord = quote! {
::core::cmp::PartialOrd::partial_cmp(&__self_disc, &__other_disc)
};
#[cfg(not(feature = "nightly"))]
let partial_ord = quote! {
const fn __discriminant<T>(__this: &Test<T>) -> isize {
match __this {
Test::A(ref __field_0) => 0,
Test::B { } => 1
}
}
::core::cmp::PartialOrd::partial_cmp(&__discriminant(self), &__discriminant(__other))
};
test_derive(
quote! {
#[derive_where(PartialEq, PartialOrd)]
enum Test<T> {
A(std::marker::PhantomData<T>),
B { },
}
},
quote! {
#[automatically_derived]
impl<T> ::core::cmp::PartialEq for Test<T> {
#[inline]
fn eq(&self, __other: &Self) -> bool {
if ::core::mem::discriminant(self) == ::core::mem::discriminant(__other) {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
true && ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
_ => true,
}
} else {
false
}
}
}
#[automatically_derived]
impl<T> ::core::cmp::PartialOrd for Test<T> {
#[inline]
fn partial_cmp(&self, __other: &Self) -> ::core::option::Option<::core::cmp::Ordering> {
#discriminant
if __self_disc == __other_disc {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
match ::core::cmp::PartialOrd::partial_cmp(__field_0, __other_field_0) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
__cmp => __cmp,
},
_ => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
}
} else {
#partial_ord
}
}
}
},
)
}
#[test]
fn tuple_unit() -> Result<()> {
#[cfg(feature = "nightly")]
let discriminant = quote! {
let __self_disc = ::core::intrinsics::discriminant_value(self);
let __other_disc = ::core::intrinsics::discriminant_value(__other);
};
#[cfg(not(feature = "nightly"))]
let discriminant = quote! {
let __self_disc = ::core::mem::discriminant(self);
let __other_disc = ::core::mem::discriminant(__other);
};
#[cfg(feature = "nightly")]
let partial_ord = quote! {
::core::cmp::PartialOrd::partial_cmp(&__self_disc, &__other_disc)
};
#[cfg(not(feature = "nightly"))]
let partial_ord = quote! {
const fn __discriminant<T>(__this: &Test<T>) -> isize {
match __this {
Test::A(ref __field_0) => 0,
Test::B() => 1
}
}
::core::cmp::PartialOrd::partial_cmp(&__discriminant(self), &__discriminant(__other))
};
test_derive(
quote! {
#[derive_where(PartialEq, PartialOrd)]
enum Test<T> {
A(std::marker::PhantomData<T>),
B(),
}
},
quote! {
#[automatically_derived]
impl<T> ::core::cmp::PartialEq for Test<T> {
#[inline]
fn eq(&self, __other: &Self) -> bool {
if ::core::mem::discriminant(self) == ::core::mem::discriminant(__other) {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
true && ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
_ => true,
}
} else {
false
}
}
}
#[automatically_derived]
impl<T> ::core::cmp::PartialOrd for Test<T> {
#[inline]
fn partial_cmp(&self, __other: &Self) -> ::core::option::Option<::core::cmp::Ordering> {
#discriminant
if __self_disc == __other_disc {
match (self, __other) {
(Test::A(ref __field_0), Test::A(ref __other_field_0)) =>
match ::core::cmp::PartialOrd::partial_cmp(__field_0, __other_field_0) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
__cmp => __cmp,
},
_ => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
}
} else {
#partial_ord
}
}
}
},
)
}