That disagrees with the following code:
use std::borrow::Borrow;
use std::collections::BTreeMap;
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
enum KeyType {
One,
Two,
}
impl Default for KeyType {
fn default() -> Self {
Self::One
}
}
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
enum KeyWrapper {
Alpha(KeyType),
Beta(KeyType),
}
impl Default for KeyWrapper {
fn default() -> Self {
Self::Alpha(KeyType::One)
}
}
impl Borrow<KeyType> for KeyWrapper {
fn borrow(&self) -> &KeyType {
match self {
Self::Alpha(ty) => &ty,
Self::Beta(ty) => &ty,
}
}
}
fn main() {
let mut map = BTreeMap::new();
map.insert(KeyWrapper::Alpha(KeyType::One), "unus");
map.insert(KeyWrapper::Alpha(KeyType::Two), "duo");
let lookup_key = Default::default();
println!("{:?}", map.get(&lookup_key));
}
(see Rust Playground).
As-is, this code does not compile, because there are two types that lookup_key
could be. If you remove the impl Borrow<KeyType> for KeyWrapper
, the code compiles.
And this is the problem case, as far as I'm concerned. I've added an extra trait implementation, which causes lookup_key
to go from "can only be KeyWrapper
" to "can be KeyType
or KeyWrapper
", and thus causing type inference of Default::default()
to fail. To avoid this, you'd need a different rule for enums than is used elsewhere, otherwise adding a trait implementation could cause this very same class of breakage.