#![cfg_attr(not(test), no_std)] #![allow(type_alias_bounds)] #![deny(missing_docs)]
#![forbid(unsafe_code)]
pub type Invariant<T: ?Sized> = r#impl::Invariant<T>;
pub type Covariant<T: ?Sized> = r#impl::Covariant<T>;
pub type Contravariant<T: ?Sized> = r#impl::Contravariant<T>;
pub type Lt<'lifetime> = r#impl::Lt<'lifetime>;
#[doc(hidden)]
pub use crate::r#impl::reexport_hack::*;
mod r#impl {
pub mod reexport_hack {
pub use super::{
Contravariant::Contravariant, Covariant::Covariant, Invariant::Invariant, Lt::Lt,
};
}
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum Never {}
pub enum Invariant<T: ?Sized> {
Invariant,
#[doc(hidden)]
#[deprecated(
since = "0.1.0",
note = "you shouldn't use `Invariant` as a enum and/or use `__Phantom` variant of it. \
This variant is only used to use the generic parameter. It's implementation \
detail and may change at any time."
)]
__Phantom(core::marker::PhantomData<fn(T) -> T>, Never),
}
pub enum Covariant<T: ?Sized> {
Covariant,
#[doc(hidden)]
#[deprecated(
since = "0.1.0",
note = "you shouldn't use `Covariant` as a enum and/or use `__Phantom` variant of it. \
This variant is only used to use the generic parameter. It's implementation \
detail and may change at any time."
)]
__Phantom(core::marker::PhantomData<fn(()) -> T>, Never),
}
pub enum Contravariant<T: ?Sized> {
Contravariant,
#[doc(hidden)]
#[deprecated(
since = "0.1.0",
note = "you shouldn't use `Contravariant` as a enum and/or use `__Phantom` variant of \
it. This variant is only used to use the generic parameter. It's \
implementation detail and may change at any time."
)]
__Phantom(core::marker::PhantomData<fn(T) -> ()>, Never),
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Lt<'a> {
Lt,
#[doc(hidden)]
#[deprecated(
since = "0.1.3",
note = "you shouldn't use `Life` as a enum and/or use `__Phantom` variant of it. This \
variant is only used to use the generic parameter. It's implementation detail \
and may change at any time."
)]
__Phantom(core::marker::PhantomData<&'a ()>, Never),
}
macro_rules! impls {
(for $T:ident) => {
impl<T: ?Sized> Copy for $T<T> {}
impl<T: ?Sized> Clone for $T<T> {
fn clone(&self) -> Self {
crate::$T
}
}
impl<T: ?Sized> Default for $T<T> {
fn default() -> Self {
crate::$T
}
}
impl<T: ?Sized> core::fmt::Debug for $T<T> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.write_str(stringify!($T))
}
}
impl<T: ?Sized> Ord for $T<T> {
fn cmp(&self, _: &Self) -> core::cmp::Ordering {
core::cmp::Ordering::Equal
}
}
impl<T: ?Sized> PartialOrd for $T<T> {
fn partial_cmp(&self, _: &Self) -> Option<core::cmp::Ordering> {
Some(core::cmp::Ordering::Equal)
}
}
impl<T: ?Sized> Eq for $T<T> {}
impl<T: ?Sized> PartialEq for $T<T> {
fn eq(&self, _: &Self) -> bool {
true
}
}
impl<T: ?Sized> core::hash::Hash for $T<T> {
fn hash<H: core::hash::Hasher>(&self, _: &mut H) {}
}
};
}
impls!(for Invariant);
impls!(for Covariant);
impls!(for Contravariant);
impl core::fmt::Debug for Lt<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("Lt")
}
}
}
#[cfg(any(test, doctest /* needed for compile_fail tests */))]
mod tests {
use crate::{Contravariant, Covariant, Invariant, Lt};
use core::mem::size_of;
type T = [u8];
const _: Invariant<T> = Invariant::<T>;
const _: Covariant<T> = Covariant::<T>;
const _: Contravariant<T> = Contravariant::<T>;
const _: Lt<'static> = Lt::<'static>;
#[test]
fn zstness() {
assert_eq!(size_of::<Invariant<T>>(), 0);
assert_eq!(size_of::<Covariant<T>>(), 0);
assert_eq!(size_of::<Contravariant<T>>(), 0);
assert_eq!(size_of::<Lt<'static>>(), 0);
}
#[test]
fn debug() {
assert_eq!(format!("{:?}", Invariant::<T>), "Invariant");
assert_eq!(format!("{:?}", Covariant::<T>), "Covariant");
assert_eq!(format!("{:?}", Contravariant::<T>), "Contravariant");
assert_eq!(format!("{:?}", Lt::<'static>), "Lt");
}
#[allow(dead_code)]
fn invariance() {}
#[allow(dead_code)]
fn covariance<'l>(arg: Covariant<Lt<'static>>) -> Covariant<Lt<'l>> {
arg
}
#[allow(dead_code)]
fn contravariance<'l>(arg: Contravariant<Lt<'l>>) -> Contravariant<Lt<'static>> {
arg
}
}