Skip to content

Commit

Permalink
treewide: Constification and other Rust 1.79 simplifications
Browse files Browse the repository at this point in the history
Merges: #115
  • Loading branch information
chrysn authored Aug 29, 2024
2 parents 337397d + ad8c467 commit fcfceb6
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 27 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "riot-wrappers"
version = "0.9.0"
authors = ["Christian Amsüss <chrysn@fsfe.org>"]
edition = "2021"
rust-version = "1.77.0"
rust-version = "1.79.0"

description = "Rust API wrappers for the RIOT operating system"
documentation = "https://rustdoc.etonomy.org/riot_wrappers/"
Expand Down
2 changes: 1 addition & 1 deletion src/led.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl<const I: u8> LED<I> {
/// It is not an error if this board does not have a LED with that number; the resulting struct
/// will be available but its methods have no effect.
pub const fn new_unchecked() -> Self {
assert!(I < 8, "RIOT only defines LED0..7");
const { assert!(I < 8, "RIOT only defines LED0..7") };
Self(())
}

Expand Down
26 changes: 22 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ pub const BOARD: &'static str = {
b
};

#[inline]
const fn assert_same_layout<A, B>() {
const {
assert!(
// assert_eq does not work in const yet as of 1.80.1
core::mem::size_of::<A>() == core::mem::size_of::<B>(),
"Incompatible pointers between c2rust and bindgen",
// const_format_args does not support that yet -- but the top line of the error spells
// out the types.
// "Incompatible pointers between c2rust and bindgen: {} has size {}, {} has size {}",
// core::any::type_name::<A>(),
// core::mem::size_of::<A>(),
// core::any::type_name::<B>(),
// core::mem::size_of::<B>(),
)
};
}

/// Cast pointers around before passing them in to functions; this is sometimes needed when a
/// struct is used from bindgen (`riot_sys::*`) but passed to a C2Rust function that uses its own
/// definition (`riot_sys::inline::*`).
Expand All @@ -67,30 +85,30 @@ pub const BOARD: &'static str = {
/// becomes a no-op.
#[inline]
fn inline_cast<A, B>(input: *const A) -> *const B {
assert_eq!(core::mem::size_of::<A>(), core::mem::size_of::<B>());
assert_same_layout::<A, B>();
input as _
}

/// `*mut` analogon to [inline_cast]
#[inline]
fn inline_cast_mut<A, B>(input: *mut A) -> *mut B {
assert_eq!(core::mem::size_of::<A>(), core::mem::size_of::<B>());
assert_same_layout::<A, B>();
input as _
}

/// `&` analogon to [inline_cast]
#[inline]
#[allow(unused)]
unsafe fn inline_cast_ref<A, B>(input: &A) -> &B {
assert_eq!(core::mem::size_of::<A>(), core::mem::size_of::<B>());
assert_same_layout::<A, B>();
core::mem::transmute(input)
}

/// `&mut` analogon to [inline_cast]
#[inline]
#[allow(unused)]
unsafe fn inline_cast_ref_mut<A, B>(input: &mut A) -> &mut B {
assert_eq!(core::mem::size_of::<A>(), core::mem::size_of::<B>());
assert_same_layout::<A, B>();
core::mem::transmute(input)
}

Expand Down
10 changes: 6 additions & 4 deletions src/msg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,12 @@ where
{
pub fn new(type_: u16, value: T) -> Self {
use core::mem::size_of;
assert!(
size_of::<T>() <= size_of::<*mut libc::c_void>(),
"Type too large to send"
);
const {
assert!(
size_of::<T>() <= size_of::<*mut libc::c_void>(),
"Type too large to send"
)
};
ContainerMsg {
message: msg_t {
type_,
Expand Down
30 changes: 17 additions & 13 deletions src/msg/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,27 +197,31 @@ pub trait MessageSemantics: Sized {
ReceivePort<NewType, NEW_TYPENO>,
SendPort<NewType, NEW_TYPENO>,
) {
// Should ideally be a static assert. Checks probably happen at build time anyway due to
// const propagation, but the panic only triggers at runtime :-(
// Should ideally be a static assert (but that depends on const trait methods). Checks
// probably happen at build time anyway due to const propagation, but the panic only
// triggers at runtime :-(
assert!(
!self.typeno_is_known(NEW_TYPENO),
"Type number is already in use for this thread."
);

// Similarly static -- better err out early
assert!(
core::mem::size_of::<NewType>()
<= core::mem::size_of::<riot_sys::msg_t__bindgen_ty_1>(),
"Type is too large to be transported in a message"
);
const {
assert!(
core::mem::size_of::<NewType>()
<= core::mem::size_of::<riot_sys::msg_t__bindgen_ty_1>(),
"Type is too large to be transported in a message"
)
};

// ... and the alignment must suffice because the data is moved in and outthrough a &mut
// SomethingTransparent<T>
assert!(
core::mem::align_of::<NewType>()
<= core::mem::align_of::<riot_sys::msg_t__bindgen_ty_1>(),
"Type has stricter alignment requirements than the message content"
);
const {
assert!(
core::mem::align_of::<NewType>()
<= core::mem::align_of::<riot_sys::msg_t__bindgen_ty_1>(),
"Type has stricter alignment requirements than the message content"
)
};

(
Processing {
Expand Down
10 changes: 6 additions & 4 deletions src/thread/tokenparts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,12 @@ impl<const MS: bool, const FS: bool> TokenParts<MS, true, FS> {
self,
f: F,
) -> ! {
assert!(
N.count_ones() == 1,
"Message queue sizes need to be powers of 2"
);
const {
assert!(
N.count_ones() == 1,
"Message queue sizes need to be powers of 2"
)
};
let mut queue: MaybeUninit<[riot_sys::msg_t; N]> = MaybeUninit::uninit();
// unsafe: All requirements of the C function are satisfied
unsafe { riot_sys::msg_init_queue(queue.as_mut_ptr() as _, N as _) };
Expand Down

0 comments on commit fcfceb6

Please sign in to comment.