diff options
| author | Zalathar <Zalathar@users.noreply.github.com> | 2024-10-25 23:34:10 +1100 |
|---|---|---|
| committer | Zalathar <Zalathar@users.noreply.github.com> | 2024-10-26 20:20:20 +1100 |
| commit | ec41e6d1b069316818dc5735e7307f24752004cd (patch) | |
| tree | f8f3ad5fac9ccc4334b23a43b23b49f1ffb4825f /compiler/rustc_codegen_llvm/src | |
| parent | b114040afbdf2366390dea7a53b8ca6fbf3f5951 (diff) | |
| download | rust-ec41e6d1b069316818dc5735e7307f24752004cd.tar.gz rust-ec41e6d1b069316818dc5735e7307f24752004cd.zip | |
Add a wrapper type for raw enum values returned by LLVM
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 10e55a4f7f6..b295331f8ec 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1,6 +1,7 @@ #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] +use std::fmt::Debug; use std::marker::PhantomData; use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t}; @@ -19,6 +20,30 @@ pub type Bool = c_uint; pub const True: Bool = 1 as Bool; pub const False: Bool = 0 as Bool; +/// Wrapper for a raw enum value returned from LLVM's C APIs. +/// +/// For C enums returned by LLVM, it's risky to use a Rust enum as the return +/// type, because it would be UB if a later version of LLVM adds a new enum +/// value and returns it. Instead, return this raw wrapper, then convert to the +/// Rust-side enum explicitly. +#[repr(transparent)] +pub struct RawEnum<T> { + value: u32, + /// We don't own or consume a `T`, but we can produce one. + _rust_side_type: PhantomData<fn() -> T>, +} + +impl<T: TryFrom<u32>> RawEnum<T> { + #[track_caller] + pub(crate) fn to_rust(self) -> T + where + T::Error: Debug, + { + // If this fails, the Rust-side enum is out of sync with LLVM's enum. + T::try_from(self.value).expect("enum value returned by LLVM should be known") + } +} + #[derive(Copy, Clone, PartialEq)] #[repr(C)] #[allow(dead_code)] // Variants constructed by C++. |
