diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2020-06-25 18:00:07 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-25 18:00:07 -0700 |
| commit | c50d9816c7b8fee1a7fa2fb7c6c47fc9b9ddd83f (patch) | |
| tree | ea0ef58a17b46f3a5cbe679c4de3276990336d12 /src/librustc_codegen_llvm | |
| parent | 23c9ac6b730f4e71b47f8714420f2609537b7114 (diff) | |
| parent | 493199626baf8a0a8f6d3a19a089165d18b3f1fb (diff) | |
| download | rust-c50d9816c7b8fee1a7fa2fb7c6c47fc9b9ddd83f.tar.gz rust-c50d9816c7b8fee1a7fa2fb7c6c47fc9b9ddd83f.zip | |
Rollup merge of #73418 - doctorn:variants-intrinsic, r=kennytm
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.)
Diffstat (limited to 'src/librustc_codegen_llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/intrinsic.rs | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 0a1cc31044a..130c0cf1877 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -206,7 +206,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } } "size_of" | "pref_align_of" | "min_align_of" | "needs_drop" | "type_id" - | "type_name" => { + | "type_name" | "variant_count" => { let value = self .tcx .const_eval_instance(ty::ParamEnv::reveal_all(), instance, None) |
