mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-23 03:59:31 +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,
|
pub secondary: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Impl
|
|
||||||
/// Implement `Key` on most primitive types.
|
/// Implement `Key` on most primitive types.
|
||||||
///
|
///
|
||||||
/// `Key::DUPLICATE` is always `false`.
|
/// `Key::DUPLICATE` is always `false`.
|
||||||
|
@ -85,12 +84,7 @@ macro_rules! impl_key {
|
||||||
impl Key for $t {
|
impl Key for $t {
|
||||||
const DUPLICATE: bool = false;
|
const DUPLICATE: bool = false;
|
||||||
type Primary = $t;
|
type Primary = $t;
|
||||||
// This 0 variant enum is unconstructable,
|
type Secondary = crate::never::Never;
|
||||||
// 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;
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn primary(self) -> Self::Primary {
|
fn primary(self) -> Self::Primary {
|
||||||
|
|
|
@ -254,6 +254,9 @@ pub use key::{DupKey, Key};
|
||||||
|
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
|
mod never;
|
||||||
|
pub(crate) use never::Never;
|
||||||
|
|
||||||
pub mod ops;
|
pub mod ops;
|
||||||
|
|
||||||
mod pod;
|
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<const N: usize> Sealed for [u8; N] {}
|
||||||
|
|
||||||
impl_sealed! {
|
impl_sealed! {
|
||||||
std::convert::Infallible,
|
crate::never::Never,
|
||||||
Vec<u8>,
|
Vec<u8>,
|
||||||
Box<[u8]>,
|
Box<[u8]>,
|
||||||
std::sync::Arc<[u8]>,
|
std::sync::Arc<[u8]>,
|
||||||
|
@ -133,10 +133,10 @@ mod private {
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Pod Impl (bytes)
|
//---------------------------------------------------------------------------------------------------- Pod Impl (bytes)
|
||||||
// Implement for `Infallible`.
|
// Implement for `Never`.
|
||||||
// This type is `!` and should never be constructable,
|
// This type is never be constructable,
|
||||||
// so all these functions will just panic.
|
// so all these functions will just panic.
|
||||||
impl Pod for std::convert::Infallible {
|
impl Pod for crate::never::Never {
|
||||||
#[cold]
|
#[cold]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn as_bytes(&self) -> impl AsRef<[u8]> {
|
fn as_bytes(&self) -> impl AsRef<[u8]> {
|
||||||
|
|
Loading…
Reference in a new issue