Strange error on assert of const struct value (possible compiler bug!)


#1

I have const value, typed as struct. It contains config data for my App. This struct have const fn default function. Typical I define my const via struct update syntax (see down).
And I want to assert fields values of my struct. This is test example, which contains incorrect value my_const.b=1025:

#![feature(const_fn)]

pub struct MyStruct {
    /// Values must be in [0..10]
    pub a: u8,
    /// Values must be in [0..1024]
    pub b: u16,
}

impl MyStruct {
    pub const fn default() -> Self {
        Self { a: 10, b: 1024 } //This is correct values!
    }
}

#[allow(non_upper_case_globals)]
pub const my_const: MyStruct = MyStruct {
    b: 1025, //Incorrect!!!
    ..MyStruct::default()
};

//Static assert for my_const.a   (1)
const CONDITION1: bool = my_const.a <= 10;
type __ASSERT1 = [i8; 0 - (!CONDITION1 as usize)];
const _tmp1: __ASSERT1 = [];

//Static assert for my_const.b   (2)
const CONDITION2: bool = my_const.b <= 1024;
type __ASSERT2 = [i8; 0 - (!CONDITION2 as usize)];
const _tmp2: __ASSERT2 = [];

fn main() {}

And I got such compiler errors:

pc@home267:~/eclipse-workspace/tmp$ cargo build
   Compiling tmp v0.1.0 (file:///home/pc/eclipse-workspace/tmp)
error[E0080]: constant evaluation error
  --> src/main.rs:23:26
   |
23 | const CONDITION1: bool = my_const.a <= 10;
   |                          ^^^^^^^^^^ nonexistent struct field
   |
note: for constant expression here
  --> src/main.rs:25:1
   |
25 | const _tmp1: __ASSERT1 = [];
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0080]: constant evaluation error
  --> src/main.rs:29:23
   |
29 | type __ASSERT2 = [i8; 0 - (!CONDITION2 as usize)];
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
   |
note: for constant expression here
  --> src/main.rs:30:1
   |
30 | const _tmp2: __ASSERT2 = [];
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

If you want more information on this error, try using "rustc --explain E0080"
error: Could not compile `tmp`.

To learn more, run the command again with --verbose.

Assert No2 got error (my_const.b = 1025 not in [0…1024]), it is good.

But assert No1 must be compiled without errors (my_const.a = 10 in [0…10])! Instead of this I got strange error:

23 | const CONDITION1: bool = my_const.a < 10;
   |                          ^^^^^^^^^^ nonexistent struct field

May be it is compiler bug?

Tools and environments:

  • Rust compiler: rustc 1.26.0-nightly (3eeb5a665 2018-03-01)
  • Target: any possible

#2

Sorry, I updated rustc to “1.26.0-nightly (521d91c6b 2018-03-14)” and now bug does not reproduce. Presumably it is fixed in #46882.
Question is closed.


#3

This thread reminds me: it’d be nice to have proper static asserts and not these homegrown C-like tricks with arrays. Perhaps Miri can enable that.