Description
Test case:
extern crate collections;
use collections::enum_set::{EnumSet, CLike};
use std::cast;
#[repr(uint)]
enum Foo {
V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
}
impl CLike for Foo {
fn to_uint(&self) -> uint {
*self as uint
}
fn from_uint(v: uint) -> Foo {
unsafe { cast::transmute(v) }
}
}
fn main() {
let mut set: EnumSet<Foo> = EnumSet::empty();
set.add(V63);
set.add(V64);
set.add(V65);
println!("{:?}", set.iter().collect::<~[Foo]>())
}
Expected result, in decreasing order of preference: ~[V63, V64, V65]
, compile-time failure, or run-time failure.
Actual result with rustc eea4909 on a 64 bit system: ~[V00, V01, V63]
Use case: Servo currently handles CSS declarations in order, later ones overwriting earlier ones. I’d like instead to process declarations in reverse order, and skip those for properties for which we already have a value. "Already have a value" would be stored in an EnumSet with one variant for every CSS property. There are a few hundreds of them. (The enum is automatically generated.) (Values can not be Option
s, because they’re initialized to the inherited or initial value rather than None
.)
Possible fixes:
- To at least avoid silently corrupting data, have the
bit
function assert (non-disablable) thate.to_uint() < (size_of<uint>() * 8)
- Do 1., and also add a
BigEnumSet
type that usesVec<uint>
or~[uint]
internally for storage rather than just a singleuint
. - Change
EnumSet
to decide at run-time to use~[uint]
or a singleuint
for storage, likecollections::bitv::Bitv
does. - Like 3., but decide at compile-time what kind of storage to use. (Since the generic
EnumSet
is being monomorphized anyway.) I don’t know if this is possible.
3 or 4 might need the CLike
trait to gain a max_value
associated function (or something), which would ideally be based on introspection rather than leaving the counting to the user.