xtask: allow anonymous unit constant

Helpful for checks such as:

```rust
const _: () = {
    assert!(size_of::<MemoryDescriptor>() == 40);
    assert!(align_of::<MemoryDescriptor>() == 8);

    assert!(offset_of!(MemoryDescriptor, ty) == 0);
    assert!(offset_of!(MemoryDescriptor, phys_start) == 8);
    assert!(offset_of!(MemoryDescriptor, virt_start) == 16);
    assert!(offset_of!(MemoryDescriptor, page_count) == 24);
    assert!(offset_of!(MemoryDescriptor, att) == 32);
};
```
This commit is contained in:
Philipp Schuster 2026-08-19 17:34:16 +02:00
parent 0cfe38cf30
commit 049cb57a09
No known key found for this signature in database

View file

@ -403,9 +403,17 @@ fn check_macro(item: &ItemMacro, src: &Path) -> Result<(), Error> {
Ok(())
}
/// True if the item is an anonymous compile-time assertion.
fn is_anonymous_unit_const(item: &ItemConst) -> bool {
item.ident == "_" && matches!(&*item.ty, Type::Tuple(tuple) if tuple.elems.is_empty())
}
/// Validate a top-level item.
fn check_item(item: &Item, src: &Path) -> Result<(), Error> {
match item {
Item::Const(item) if is_anonymous_unit_const(item) => {
// Allow compile-time assertions such as ABI layout checks.
}
Item::Const(ItemConst { vis, ty, .. }) => {
if !is_pub(vis) {
return Err(Error::new(ErrorKind::MissingPub, src, item));
@ -518,6 +526,30 @@ mod tests {
);
}
#[test]
fn test_anonymous_unit_const() {
// Compile-time assertions do not form part of the public API.
assert!(
check_item(
&parse_quote! {
const _: () = {
assert!(true);
};
},
src(),
)
.is_ok()
);
// Named constants must remain public.
check_item_err(
parse_quote! {
const PRIVATE: () = ();
},
ErrorKind::MissingPub,
);
}
#[test]
fn test_macro() {
// bitflags `repr` must be transparent.