about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-06-25 18:00:07 -0700
committerGitHub <noreply@github.com>2020-06-25 18:00:07 -0700
commitc50d9816c7b8fee1a7fa2fb7c6c47fc9b9ddd83f (patch)
treeea0ef58a17b46f3a5cbe679c4de3276990336d12 /src/librustc_codegen_llvm
parent23c9ac6b730f4e71b47f8714420f2609537b7114 (diff)
parent493199626baf8a0a8f6d3a19a089165d18b3f1fb (diff)
downloadrust-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.rs2
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)