]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #73418 - doctorn:variants-intrinsic, r=kennytm
authorManish Goregaokar <manishsmail@gmail.com>
Fri, 26 Jun 2020 01:00:07 +0000 (18:00 -0700)
committerGitHub <noreply@github.com>
Fri, 26 Jun 2020 01:00:07 +0000 (18:00 -0700)
Add unstable `core::mem::variant_count` intrinsic

Adds a new `const fn` intrinsic which can be used to determine the number of variants in an `enum`.

I've shown this to a couple of people and they invariably ask 'why on earth?', but there's actually a very neat use case:

At the moment, if you want to create an opaque array type that's indexed by an `enum` with one element for each variant, you either have to hard-code the number of variants, add a `LENGTH` variant or use a `Vec`, none of which are suitable in general (number of variants could change; pattern matching `LENGTH` becomes frustrating; might not have `alloc`). By including this intrinsic, it becomes possible to write the following:

```rust
#[derive(Copy, Clone)]
enum OpaqueIndex {
    A = 0,
    B,
    C,
}

struct OpaqueVec<T>(Box<[T; std::mem::num_variants::<OpaqueIndex>()]>);

impl<T> std::ops::Index<OpaqueIndex> for OpaqueVec<T> {
    type Output = T;

    fn index(&self, idx: OpaqueIndex) -> &Self::Output {
        &self.0[idx as usize]
    }
}
```

(We even have a use cases for this in `rustc` and I plan to use it to re-implement the lang-items table.)

1  2 
src/libcore/intrinsics.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_span/symbol.rs

Simple merge
Simple merge