Skip to content

Commit 455a67b

Browse files
committed
Replace the llvm::Bool typedef with a proper newtype
1 parent 4eedad3 commit 455a67b

File tree

8 files changed

+75
-34
lines changed

8 files changed

+75
-34
lines changed

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use tracing::debug;
1616
use crate::builder::Builder;
1717
use crate::common::Funclet;
1818
use crate::context::CodegenCx;
19+
use crate::llvm::ToLlvmBool;
1920
use crate::type_::Type;
2021
use crate::type_of::LayoutLlvmExt;
2122
use crate::value::Value;
@@ -470,10 +471,6 @@ pub(crate) fn inline_asm_call<'ll>(
470471
dest: Option<&'ll llvm::BasicBlock>,
471472
catch_funclet: Option<(&'ll llvm::BasicBlock, Option<&Funclet<'ll>>)>,
472473
) -> Option<&'ll Value> {
473-
let volatile = if volatile { llvm::True } else { llvm::False };
474-
let alignstack = if alignstack { llvm::True } else { llvm::False };
475-
let can_throw = if unwind { llvm::True } else { llvm::False };
476-
477474
let argtys = inputs
478475
.iter()
479476
.map(|v| {
@@ -500,10 +497,10 @@ pub(crate) fn inline_asm_call<'ll>(
500497
asm.len(),
501498
cons.as_ptr(),
502499
cons.len(),
503-
volatile,
504-
alignstack,
500+
volatile.to_llvm_bool(),
501+
alignstack.to_llvm_bool(),
505502
dia,
506-
can_throw,
503+
unwind.to_llvm_bool(),
507504
)
508505
};
509506

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::attributes;
3535
use crate::common::Funclet;
3636
use crate::context::{CodegenCx, FullCx, GenericCx, SCx};
3737
use crate::llvm::{
38-
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True,
38+
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, GEPNoWrapFlags, Metadata, ToLlvmBool, True,
3939
};
4040
use crate::type_::Type;
4141
use crate::type_of::LayoutLlvmExt;
@@ -717,7 +717,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
717717
let mut const_llval = None;
718718
let llty = place.layout.llvm_type(self);
719719
if let Some(global) = llvm::LLVMIsAGlobalVariable(place.val.llval) {
720-
if llvm::LLVMIsGlobalConstant(global) == llvm::True {
720+
if llvm::LLVMIsGlobalConstant(global).is_true() {
721721
if let Some(init) = llvm::LLVMGetInitializer(global) {
722722
if self.val_ty(init) == llty {
723723
const_llval = Some(init);
@@ -1067,13 +1067,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
10671067

10681068
fn intcast(&mut self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value {
10691069
unsafe {
1070-
llvm::LLVMBuildIntCast2(
1071-
self.llbuilder,
1072-
val,
1073-
dest_ty,
1074-
if is_signed { True } else { False },
1075-
UNNAMED,
1076-
)
1070+
llvm::LLVMBuildIntCast2(self.llbuilder, val, dest_ty, is_signed.to_llvm_bool(), UNNAMED)
10771071
}
10781072
}
10791073

@@ -1317,7 +1311,6 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13171311
failure_order: rustc_middle::ty::AtomicOrdering,
13181312
weak: bool,
13191313
) -> (&'ll Value, &'ll Value) {
1320-
let weak = if weak { llvm::True } else { llvm::False };
13211314
unsafe {
13221315
let value = llvm::LLVMBuildAtomicCmpXchg(
13231316
self.llbuilder,
@@ -1328,7 +1321,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13281321
AtomicOrdering::from_generic(failure_order),
13291322
llvm::False, // SingleThreaded
13301323
);
1331-
llvm::LLVMSetWeak(value, weak);
1324+
llvm::LLVMSetWeak(value, weak.to_llvm_bool());
13321325
let val = self.extract_value(value, 0);
13331326
let success = self.extract_value(value, 1);
13341327
(val, success)
@@ -1368,14 +1361,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13681361
scope: SynchronizationScope,
13691362
) {
13701363
let single_threaded = match scope {
1371-
SynchronizationScope::SingleThread => llvm::True,
1372-
SynchronizationScope::CrossThread => llvm::False,
1364+
SynchronizationScope::SingleThread => true,
1365+
SynchronizationScope::CrossThread => false,
13731366
};
13741367
unsafe {
13751368
llvm::LLVMBuildFence(
13761369
self.llbuilder,
13771370
AtomicOrdering::from_generic(order),
1378-
single_threaded,
1371+
single_threaded.to_llvm_bool(),
13791372
UNNAMED,
13801373
);
13811374
}

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use tracing::debug;
2020
use crate::consts::const_alloc_to_llvm;
2121
pub(crate) use crate::context::CodegenCx;
2222
use crate::context::{GenericCx, SCx};
23-
use crate::llvm::{self, BasicBlock, Bool, ConstantInt, False, Metadata, True};
23+
use crate::llvm::{self, BasicBlock, ConstantInt, False, Metadata, ToLlvmBool, True};
2424
use crate::type_::Type;
2525
use crate::value::Value;
2626

@@ -392,7 +392,7 @@ fn struct_in_context<'ll>(
392392
packed: bool,
393393
) -> &'ll Value {
394394
let len = c_uint::try_from(elts.len()).expect("LLVMConstStructInContext elements len overflow");
395-
unsafe { llvm::LLVMConstStructInContext(llcx, elts.as_ptr(), len, packed as Bool) }
395+
unsafe { llvm::LLVMConstStructInContext(llcx, elts.as_ptr(), len, packed.to_llvm_bool()) }
396396
}
397397

398398
#[inline]

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#![allow(non_camel_case_types)]
1414
#![allow(non_upper_case_globals)]
1515

16-
use std::fmt::Debug;
16+
use std::fmt::{self, Debug};
1717
use std::marker::PhantomData;
1818
use std::num::NonZero;
1919
use std::ptr;
@@ -33,10 +33,59 @@ use crate::llvm;
3333

3434
/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
3535
/// which has a different ABI from Rust or C++ `bool`.
36-
pub(crate) type Bool = c_int;
36+
///
37+
/// This wrapper does not implement `PartialEq`.
38+
/// To test the underlying boolean value, use [`Self::is_true`].
39+
#[derive(Clone, Copy)]
40+
#[repr(transparent)]
41+
pub(crate) struct Bool {
42+
value: c_int,
43+
}
44+
45+
pub(crate) const True: Bool = Bool::TRUE;
46+
pub(crate) const False: Bool = Bool::FALSE;
47+
48+
impl Bool {
49+
pub(crate) const TRUE: Self = Self { value: 1 };
50+
pub(crate) const FALSE: Self = Self { value: 0 };
51+
52+
pub(crate) const fn from_bool(rust_bool: bool) -> Self {
53+
if rust_bool { Self::TRUE } else { Self::FALSE }
54+
}
55+
56+
/// Converts this LLVM-C boolean to a Rust `bool`
57+
pub(crate) fn is_true(self) -> bool {
58+
// Since we're interacting with a C API, follow the C convention of
59+
// treating any nonzero value as true.
60+
self.value != Self::FALSE.value
61+
}
62+
}
3763

38-
pub(crate) const True: Bool = 1 as Bool;
39-
pub(crate) const False: Bool = 0 as Bool;
64+
impl Debug for Bool {
65+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66+
match self.value {
67+
0 => f.write_str("FALSE"),
68+
1 => f.write_str("TRUE"),
69+
// As with `Self::is_true`, treat any nonzero value as true.
70+
v => write!(f, "TRUE ({v})"),
71+
}
72+
}
73+
}
74+
75+
/// Convenience trait to convert `bool` to `llvm::Bool` with an explicit method call.
76+
///
77+
/// Being able to write `b.to_llvm_bool()` is less noisy than `llvm::Bool::from(b)`,
78+
/// while being more explicit and less mistake-prone than something like `b.into()`.
79+
pub(crate) trait ToLlvmBool: Copy {
80+
fn to_llvm_bool(self) -> llvm::Bool;
81+
}
82+
83+
impl ToLlvmBool for bool {
84+
#[inline(always)]
85+
fn to_llvm_bool(self) -> llvm::Bool {
86+
llvm::Bool::from_bool(self)
87+
}
88+
}
4089

4190
/// Wrapper for a raw enum value returned from LLVM's C APIs.
4291
///

compiler/rustc_codegen_llvm/src/llvm/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ pub(crate) fn set_initializer(llglobal: &Value, constant_val: &Value) {
215215
}
216216

217217
pub(crate) fn set_global_constant(llglobal: &Value, is_constant: bool) {
218-
LLVMSetGlobalConstant(llglobal, if is_constant { ffi::True } else { ffi::False });
218+
LLVMSetGlobalConstant(llglobal, is_constant.to_llvm_bool());
219219
}
220220

221221
pub(crate) fn get_linkage(llglobal: &Value) -> Linkage {
@@ -229,7 +229,7 @@ pub(crate) fn set_linkage(llglobal: &Value, linkage: Linkage) {
229229
}
230230

231231
pub(crate) fn is_declaration(llglobal: &Value) -> bool {
232-
unsafe { LLVMIsDeclaration(llglobal) == ffi::True }
232+
unsafe { LLVMIsDeclaration(llglobal) }.is_true()
233233
}
234234

235235
pub(crate) fn get_visibility(llglobal: &Value) -> Visibility {

compiler/rustc_codegen_llvm/src/llvm_util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static INIT: Once = Once::new();
2626
pub(crate) fn init(sess: &Session) {
2727
unsafe {
2828
// Before we touch LLVM, make sure that multithreading is enabled.
29-
if llvm::LLVMIsMultithreaded() != 1 {
29+
if !llvm::LLVMIsMultithreaded().is_true() {
3030
bug!("LLVM compiled without support for threads");
3131
}
3232
INIT.call_once(|| {

compiler/rustc_codegen_llvm/src/mono_item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl CodegenCx<'_, '_> {
133133

134134
// Thread-local variables generally don't support copy relocations.
135135
let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
136-
.is_some_and(|v| llvm::LLVMIsThreadLocal(v) == llvm::True);
136+
.is_some_and(|v| llvm::LLVMIsThreadLocal(v).is_true());
137137
if is_thread_local_var {
138138
return false;
139139
}

compiler/rustc_codegen_llvm/src/type_.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_target::callconv::{CastTarget, FnAbi};
1515
use crate::abi::{FnAbiLlvmExt, LlvmType};
1616
use crate::context::{CodegenCx, GenericCx, SCx};
1717
pub(crate) use crate::llvm::Type;
18-
use crate::llvm::{Bool, False, Metadata, True};
18+
use crate::llvm::{False, Metadata, ToLlvmBool, True};
1919
use crate::type_of::LayoutLlvmExt;
2020
use crate::value::Value;
2121
use crate::{common, llvm};
@@ -53,7 +53,9 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
5353
}
5454

5555
pub(crate) fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) {
56-
unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) }
56+
unsafe {
57+
llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed.to_llvm_bool())
58+
}
5759
}
5860
pub(crate) fn type_void(&self) -> &'ll Type {
5961
unsafe { llvm::LLVMVoidTypeInContext(self.llcx()) }
@@ -152,7 +154,7 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
152154
self.llcx(),
153155
els.as_ptr(),
154156
els.len() as c_uint,
155-
packed as Bool,
157+
packed.to_llvm_bool(),
156158
)
157159
}
158160
}

0 commit comments

Comments
 (0)