I consider to deprecate this implementation in mmtkvdb (and instead provide different unit types for keys and values). However, it looks like Rust doesn't support deprecation for impls. Example:
Compiling playground v0.0.1 (/playground)
error: this `#[deprecated]` annotation has no effect
--> src/lib.rs:5:1
|
5 | #[deprecated]
| ^^^^^^^^^^^^^ help: remove the unnecessary deprecation attribute
|
= note: `#[deny(useless_deprecated)]` on by default
error: could not compile `playground` due to previous error
What's the best way to go when you want to deprecate an impl?
I found a way using associated constants to cause a custom compiler error whenever an implementation is used (which can be suppressed by requesting a crate feature then). I don't think I will use it, but want to share it nonetheless:
pub trait Tr {
const _DEPRECATE: () = ();
fn repr(&self) -> &[u8];
}
struct NoValue;
impl Tr for NoValue {
fn repr(&self) -> &[u8] {
b""
}
}
trait DeprecateTr {}
impl DeprecateTr for () {}
impl<T: ?Sized + DeprecateTr> Tr for T {
const _DEPRECATE: () = {
#[cfg(not(feature = "compat"))]
panic!("Implementation of Tr for () is deprecated. Enable feature 'compat' to suppress this error.");
};
fn repr(&self) -> &[u8] {
let _ = Self::_DEPRECATE;
b"\x00"
}
}
fn main() {
assert_eq!(NoValue.repr(), b"");
// The following line gives a custom compile time error
// unless the `compat` feature is used:
//assert_eq!(().repr(), b"\x00");
}
Not sure, however, if it's guaranteed that the constant doesn't get evaluated unless the trait implementation is used. But I feel like it's too hackery anyway.
const fn impl_deprecated() {
#[cfg(not(feature = "compat"))]
- panic!("Implementation of Tr for () is deprecated. Enable feature 'compat' to suppress this error.");
+ compile_error!("Implementation of Tr for () is deprecated. Enable feature 'compat' to suppress this error.");
}