Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use generated bitflags to initialise a const #180

Closed
PhilipDaniels opened this issue Jun 5, 2019 · 4 comments
Closed

Can't use generated bitflags to initialise a const #180

PhilipDaniels opened this issue Jun 5, 2019 · 4 comments

Comments

@PhilipDaniels
Copy link

PhilipDaniels commented Jun 5, 2019

This works in plain Rust

const MAMMAL: u8 = 1;
const AQUATIC: u8 = 2;
const SEAL: u8 = MAMMAL | AQUATIC;

but the equivalent when using bitflags does not

use bitflags::bitflags;

bitflags! {
    pub struct FLAGS: u8 {
        const MAMMAL  = 1;
        const AQUATIC = 2;
    }
}

const SECOND_SEAL: FLAGS = FLAGS::MAMMAL | FLAGS::AQUATIC;

You get an error error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants when trying to BITOR the two flags.

It would be nice if it did, because in my program I have a large initial array of flags to create and there are many different combinations making it impractical to spell them all out inside the bitflags! call.

Edit: Simplified the repro.

@KodrAus
Copy link
Member

KodrAus commented Jun 6, 2019

So this is a little unfortunate. It seems like a limitation in Rust's const evaluation where operators on primitive types are specially understood as being available in a constant context. We can't mark our BitOr implementation as being constant, even though it is.

One workaround is to do something like this:

const SECOND_SEAL: FLAGS = FLAGS::from_bits_truncate(FLAGS::MAMMAL.bits() | FLAGS::AQUATIC.bits());

@PhilipDaniels
Copy link
Author

Thanks.

I wondered whether it was possible to mark BitOr as const fn or something...but I don't follow the rustc improvements that closely. I worked around my issue my not using bitflags, instead I declared an empty struct and gave it some associated constants.

@ArekPiekarz
Copy link

If it is a Rust limitation, should an issue about it be reported on their github?

@KodrAus
Copy link
Member

KodrAus commented Aug 3, 2021

There's some experimental work to support const trait impls that should enable using bitops here: rust-lang/rust#67792 but it sounds like there's still a lot of work to be done before that will reach us.

In the meantime, we just merged in #244 which includes some nicer const set operators that avoids the need to wrap integers. So your second example could become:

const SECOND_SEAL: FLAGS = FLAGS::MAMMAL.union(FLAGS::AQUATIC);

@KodrAus KodrAus closed this as completed May 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants