Enum size overflow detection

I know using match ensures that all values of an enum are handled, but what about when an enum is #[repr()]?

I can think of two situations:

  1. The as overflow, when some values would cause an overflow in the conversion. All values must translate to the given type. If there is a value 256 then as u8 should fail.

  2. The array index, when an array is indexed by enum as usize. The array(not slice) must be large enough to be indexed by every enum value.

I looked for enum size/max value to use for an array size, but then I remembered that rust is more about failing to compile VS auto detection. I still couldn't find anything about these two requirements.

Also might I suggest a compiler warning about wrong repr(). If the enum is only ever used as T then the repr should also be T, for when we are sure these are the only uses of the enum.

@cheako I do not understand your question. match is no different for enums with and without repr, and there is no addition involved so there cannot be an overflow either.

Maybe it would help if you gave a concrete example?

1 Like

I'm unfamiliar with the syntax.

  1. enum T ( Tb = 265); let a: T = _; ... a as u8;
  2. enum T ( Tb = 3 ); let a: [A; 2] = _; let b: T = _; ... a[b];

Both situations are fail, the first because if a is Tb it can't be as u8. The second because if b is Tb then a[b] reads past the end.

  1. In this case a as u8 is a silent truncation. It's only an error for you if you did not intend that; it's not an error for everyone. There are many valid reasons to want to truncate. My most frequent use is to extract the low-order u32 from a u64.

  2. This is an error that Rust will catch, either at compile-time or at run-time. There's no way for it to execute as specified.

I suggest you try various things you are wondering about on the Playground. For example, here's your second example. As you can see, it does not even compile:

error[E0277]: the type `[{integer}]` cannot be indexed by `T`
 --> src/main.rs:6:16
  |
6 |     let _val = a[b];
  |                ^^^^ slice indices are of type `usize` or ranges of `usize`
  |
  = help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `T`
  = note: required because of the requirements on the impl of `std::ops::Index<T>` for `[{integer}]`

There are great resources available online for learning Rust. :slight_smile: This is not a beginner's forum, I am afraid. It is called "internals" for a reason. There's a dedicated forum for using Rust for questions such as this.

5 Likes

For enum truncation is almost certainly an error.

If such truncation is intended to be an error, then use a checked conversion rather than the unchecked cast as. See the Rust Reference section about as to understand how intentionally powerful that operator is.

This already is a compile error

2 Likes