diff --git a/database/src/key.rs b/database/src/key.rs
index 69beff0d..4adb6cd7 100644
--- a/database/src/key.rs
+++ b/database/src/key.rs
@@ -71,7 +71,6 @@ pub struct DupKey
{
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":
- // .
- //
- // FIXME: Use the `!` type when stable.
- type Secondary = std::convert::Infallible;
+ type Secondary = crate::never::Never;
#[inline(always)]
fn primary(self) -> Self::Primary {
diff --git a/database/src/lib.rs b/database/src/lib.rs
index db23a49a..31dee852 100644
--- a/database/src/lib.rs
+++ b/database/src/lib.rs
@@ -254,6 +254,9 @@ pub use key::{DupKey, Key};
mod macros;
+mod never;
+pub(crate) use never::Never;
+
pub mod ops;
mod pod;
diff --git a/database/src/never.rs b/database/src/never.rs
new file mode 100644
index 00000000..fd9325f6
--- /dev/null
+++ b/database/src/never.rs
@@ -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":
+/// .
+///
+/// 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;
+
+ fn page_references(&self) -> Self::PageReferences {
+ unreachable!()
+ }
+ }
+ }
+}
diff --git a/database/src/pod.rs b/database/src/pod.rs
index b7c1ed7d..3ce55e16 100644
--- a/database/src/pod.rs
+++ b/database/src/pod.rs
@@ -111,7 +111,7 @@ mod private {
impl Sealed for [u8; N] {}
impl_sealed! {
- std::convert::Infallible,
+ crate::never::Never,
Vec,
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]> {