hecatia-elegua / bilge

Use bitsized types as if they were a feature of rust.
Apache License 2.0
171 stars 17 forks source link

bitsize macro doesn't handle generic type that implements Bitsized correctly without manually including a turbofish #76

Closed kitlith closed 1 year ago

kitlith commented 1 year ago

quick minimal example:

use std::marker::PhantomData;
use bilge::prelude::*;

struct Inner<T>(PhantomData<T>);
impl<T> Bitsized for Inner<T> {
    type ArbitraryInt = u1;

    const BITS: usize = 1;

    const MAX: Self::ArbitraryInt = <u1 as Bitsized>::MAX;
}

impl<T> From<u1> for Inner<T> {
    fn from(val: u1) -> Self {
        Self(PhantomData)
    }
}

#[bitsize(1)]
struct Minimal {
    // value: Inner<()> // "Error: comparison operators cannot be chained"
    value: Inner::<()> // works
}

This appears to happen because the macro repeats the type verbatim within the methods it generates, but in that context the compiler can't assume that it's a type, therefore the turbofish needs to be present.

Workaround is to turbofish the type specification inside the struct.