Why doesn't this 'increment then decrement' generic const expression work in Rust?

67 views Asked by At

I've been trying to make some of my code more airtight by moving some runtime operations to compile time. I thought it would be simpler because I'm only trying to increment or decrement a number by one, but I'm running into some disagreements with rustc.

Here's a small display of the problem.

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

struct Number<const VALUE: usize>;

impl<const VALUE: usize> Number<VALUE> {
    fn new() -> Number<0> {
        Number::<0>
    }

    fn increment(self) -> Number<{VALUE + 1}> {
        Number::<{VALUE + 1}>
    }
    
    fn decrement(self) -> Number<{VALUE - 1}> {
        Number::<{VALUE - 1}>
    }
}

fn increment_decrement<const VALUE: usize>(number: Number<VALUE>) -> Number<VALUE> where [(); {VALUE - 1}]:, [(); {VALUE + 1}]: {
    number.increment().decrement()
}

fn main() {}

I have tried adding where bounds to this example in a number of different ways but it only seems to make the problem worse. This is the the version of the example that seems to give me the least errors. Said errors are:

error: unconstrained generic constant
  --> src/main.rs:21:24
   |
21 |     number.increment().decrement()
   |                        ^^^^^^^^^
   |
   = help: try adding a `where` bound using this expression: `where [(); {VALUE - 1}]:`
note: required by a bound in `Number::<VALUE>::decrement`
  --> src/main.rs:15:34
   |
15 |     fn decrement(self) -> Number<{VALUE - 1}> {
   |                                  ^^^^^^^^^^^ required by this bound in `Number::<VALUE>::decrement`

error[E0308]: mismatched types
  --> src/main.rs:21:5
   |
21 |     number.increment().decrement()
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `VALUE`, found `{VALUE - 1}`
   |
   = note: expected constant `VALUE`
              found constant `{VALUE - 1}`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` (bin "playground") due to 2 previous errors

I'm a bit confused because I've already added the where [(); {VALUE - 1}]: bound to increment_decrement and yet it's still complaining.

0

There are 0 answers