Checking at compile time if a given associated const is true

I am currently trying to have a function you can only call/compile when a given associated const is true. My current try is: Rust Playground, but that is not successful as it gives me this error:

error: generic parameters may not be used in const operations
  --> src/main.rs:19:13
   |
19 |     Check<{ T::STREAM }>: True,
   |             ^^^^^^^^^ cannot perform const operation using `T`
   |
   = note: type parameters may not be used in const expressions

I understand that this area of Rust is still a WIP, but is there an alternative I could use? I am fine with it producing potentially confusing errors.

Here's a stupid workaround.

use core::marker::PhantomData;

struct Check<T: Accept>(PhantomData<T>);
impl<T: Accept> Check<T> {
    const CHECK: () = assert!(T::STREAM);
}

trait Accept {
    type Foo;
    const STREAM: bool = false;
}

impl Accept for u64 {
    type Foo = u64;
    const STREAM: bool = false;
}

fn only_stream<T: Accept>(t: T)
{
    let _ = Check::<T>::CHECK;
    println!("Is stream!");
}

fn main() {
    only_stream(5u64);
}

Basically a desugared inline_const. But it get the work done.

edit: P.S. I actually don't really like a post-mono error approach like this. But if this is your only reasonable approach then do it. But you need to provide a reason why T: Accept<STREAM = true> is not acceptable.

1 Like

You can use nightly and enable the generic_const_exprs feature:

#![feature(generic_const_exprs)]

struct Check<const B: bool> {}

trait True {}

impl True for Check<true> {}

trait Accept {
    type Foo;
    const STREAM: bool = false;
}

impl Accept for u64 {
    type Foo = u64;
    const STREAM: bool = false;
}

impl Accept for Vec<u64> {
    type Foo = u64;
    const STREAM: bool = true;
}

fn only_stream<T: Accept>(t: T)
where
    Check<{ T::STREAM }>: True,
{
    println!("Is stream!");
}

fn main() {
    only_stream(5u64);
    only_stream(vec![5, 6, 7]);
}

Playground.

1 Like

I would have loved to do that, but trying it out gives me:

error[E0658]: associated const equality is incomplete
  --> src/main.rs:18:26
   |
18 | fn only_stream<T: Accept<STREAM = true>>(t: T)
   |                          ^^^^^^^^^^^^^
   |
   = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information

Your suggestion with the assert works well, and is sufficient until @jofas suggestion is stable.

Thank you both!

Oh. I somehow missed that... :joy:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.