Const generics: how to impl "not equal"

I cooked up this monstrosity.

#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

pub struct Foo<const I: i32> {}

impl<const I: i32> Foo<I>
where
    Boolean<{ is_zero(I) }>: Marker,
{
    pub fn new() -> Self {
        Foo {}
    }
}

fn main() {
    let a: Foo<1> = Foo::new();
    let b: Foo<0> = Foo::new();
}

struct Boolean<const B: bool>;

const fn is_zero(n: i32) -> bool {
    n == 0
}

trait Marker {}
impl Marker for Boolean<false> {}

(playground)

It correctly points to the b line as an error:

   Compiling playground v0.0.1 (/playground)
error[E0599]: the function or associated item `new` exists for struct `Foo<0_i32>`, but its trait bounds were not satisfied
  --> src/main.rs:17:23
   |
4  | pub struct Foo<const I: i32> {}
   | ---------------------------- function or associated item `new` not found for this
...
17 |     let b = Foo::<0>::new();
   |                       ^^^ function or associated item cannot be called on `Foo<0_i32>` due to unsatisfied trait bounds
...
20 | struct Boolean<const B: bool>;
   | ------------------------------ doesn't satisfy `Boolean<{ is_zero(I) }>: Marker`
   |
   = note: the following trait bounds were not satisfied:
           `Boolean<{ is_zero(I) }>: Marker`
note: the following trait must be implemented
  --> src/main.rs:26:1
   |
26 | trait Marker {}
   | ^^^^^^^^^^^^^^^
4 Likes