Conditional compilation based on generic constant

It's cumbersome (especially because the trait solver does not realize that if const B: bool, then either B == true, or B == false), but it can be done:

trait RecordKeyType { type Key : ?Sized; }

struct __<const UNICODE_KEYS: bool>;

impl RecordKeyType for __<true> {
    type Key = String;
}
impl RecordKeyType for __<false> {
    type Key = Box<[u8]>;
}

struct Record<const UNICODE_KEYS: bool>
where
    __<UNICODE_KEYS> : RecordKeyType,
{
    key: <__<UNICODE_KEYS> as RecordKeyType>::Key,
}

fn _checks (
    yes: Record::<true>,
    no: Record::<false>,
)
{
    let _: String = yes.key;
    let _: Box<[u8]> = no.key;
}

EDIT: Actually, we can use the Record type as the one given as input to the trait, removing the need for the __<…> "const-to-type lifter":

trait ResolveKeyType { type T : ?Sized; }

impl ResolveKeyType for Record<true> {
    type T = String;
}
impl ResolveKeyType for Record<false> {
    type T = Box<[u8]>;
}

struct Record<const UNICODE_KEYS: bool>
where
    Self : ResolveKeyType, // where `UNICODE_KEYS` is `true` or `false`
{
    key: <Self as ResolveKeyType>::T,
}
4 Likes