mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-22 19:49:28 +00:00
add Never
type to allow foreign trait implementations
This is a newtype to workaround `sanakirja::Storable` not being able to be implemented on `std::convert::Infallible` due to "foreign trait on foreign type" rules.
This commit is contained in:
parent
ddce2fa70c
commit
034284808a
4 changed files with 42 additions and 11 deletions
|
@ -71,7 +71,6 @@ pub struct DupKey<P, S> {
|
|||
pub secondary: S,
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Impl
|
||||
/// Implement `Key` on most primitive types.
|
||||
///
|
||||
/// `Key::DUPLICATE` is always `false`.
|
||||
|
@ -85,12 +84,7 @@ macro_rules! impl_key {
|
|||
impl Key for $t {
|
||||
const DUPLICATE: bool = false;
|
||||
type Primary = $t;
|
||||
// This 0 variant enum is unconstructable,
|
||||
// and "has the same role as the ! “never” type":
|
||||
// <https://doc.rust-lang.org/std/convert/enum.Infallible.html#future-compatibility>.
|
||||
//
|
||||
// FIXME: Use the `!` type when stable.
|
||||
type Secondary = std::convert::Infallible;
|
||||
type Secondary = crate::never::Never;
|
||||
|
||||
#[inline(always)]
|
||||
fn primary(self) -> Self::Primary {
|
||||
|
|
|
@ -254,6 +254,9 @@ pub use key::{DupKey, Key};
|
|||
|
||||
mod macros;
|
||||
|
||||
mod never;
|
||||
pub(crate) use never::Never;
|
||||
|
||||
pub mod ops;
|
||||
|
||||
mod pod;
|
||||
|
|
34
database/src/never.rs
Normal file
34
database/src/never.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
//! The never `!` type, in stable Rust.
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Table
|
||||
/// Unconstructable never `!` type.
|
||||
///
|
||||
/// This is just a newtype around [`Infallible`], it is needed
|
||||
/// because `cuprate_database` needs to implement serialization
|
||||
/// traits (even if not used) to satisfy traits bounds, but
|
||||
/// we cannot implement a foreign trait (e.g [`sanakirja::Storable`])
|
||||
/// on a foreign type ([`Infallible`]).
|
||||
///
|
||||
/// This needs to be a local type to `cuprate_database`,
|
||||
/// so unfortunately it cannot be in `cuprate_helper`.
|
||||
///
|
||||
/// `Infallible` is a 0 variant enum that is unconstructable,
|
||||
/// it "has the same role as the ! “never” type":
|
||||
/// <https://doc.rust-lang.org/std/convert/enum.Infallible.html#future-compatibility>.
|
||||
///
|
||||
/// FIXME: Use the `!` type when stable.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Never(std::convert::Infallible);
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Impl
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(all(feature = "sanakirja", not(feature = "heed")))] {
|
||||
impl sanakirja::Storable for Never {
|
||||
type PageReferences = core::iter::Empty<u64>;
|
||||
|
||||
fn page_references(&self) -> Self::PageReferences {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -111,7 +111,7 @@ mod private {
|
|||
impl<const N: usize> Sealed for [u8; N] {}
|
||||
|
||||
impl_sealed! {
|
||||
std::convert::Infallible,
|
||||
crate::never::Never,
|
||||
Vec<u8>,
|
||||
Box<[u8]>,
|
||||
std::sync::Arc<[u8]>,
|
||||
|
@ -133,10 +133,10 @@ mod private {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Pod Impl (bytes)
|
||||
// Implement for `Infallible`.
|
||||
// This type is `!` and should never be constructable,
|
||||
// Implement for `Never`.
|
||||
// This type is never be constructable,
|
||||
// so all these functions will just panic.
|
||||
impl Pod for std::convert::Infallible {
|
||||
impl Pod for crate::never::Never {
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
fn as_bytes(&self) -> impl AsRef<[u8]> {
|
||||
|
|
Loading…
Reference in a new issue