Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@

- Fix issue in C++ bindings where `diplomat::result::Ok` and `Err` have ambiguous template deduction errors in their constructors, on Clang. (https://github.com/unicode-org/icu4x/pull/4615)
- `icu_capi@1.4.1`
- Stricter version dependency on data crates
- `icu_properties@1.4.2`, `icu_normalizer@1.4.3`, `icu_properties_data@1.4.1`
- Enforce C,packed, not just packed, on ULE types, fixing for incoming changes to `repr(Rust)` (https://github.com/unicode-org/icu4x/pull/5049)
- `icu_casemap@1.4.1`, `icu_properties@1.4.3`
- A full fix also needs `zerovec@0.10.3`,`zerovec_derive@0.10.3`


## icu4x 1.4 (Nov 16, 2023)

Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion components/casemap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ homepage.workspace = true
include.workspace = true
repository.workspace = true
rust-version.workspace = true
version.workspace = true
version = "1.4.1"

[package.metadata.docs.rs]
all-features = true
Expand Down
2 changes: 1 addition & 1 deletion components/casemap/src/provider/exceptions_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl ExceptionHeader {
/// In this struct the RESERVED bit is still allowed to be set, and it will produce a different
/// exception header, but it will not have any other effects.
#[derive(Copy, Clone, PartialEq, Eq, ULE)]
#[repr(packed)]
#[repr(C, packed)]
pub struct ExceptionHeaderULE {
slot_presence: SlotPresence,
bits: ExceptionBitsULE,
Expand Down
2 changes: 1 addition & 1 deletion components/properties/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name = "icu_properties"
description = "Definitions for Unicode properties"
license-file = "LICENSE"

version = "1.4.2"
version = "1.4.3"
authors.workspace = true
categories.workspace = true
edition.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion components/properties/src/provider/bidi_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ pub enum CheckedBidiPairedBracketType {
#[doc(hidden)]
/// needed for datagen but not intended for users
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
#[repr(packed)]
#[repr(C, packed)]
pub struct MirroredPairedBracketDataULE([u8; 3]);

// Safety (based on the safety checklist on the ULE trait):
Expand Down
4 changes: 4 additions & 0 deletions provider/datagen/tests/data/postcard/fingerprints.csv
Original file line number Diff line number Diff line change
Expand Up @@ -4889,6 +4889,7 @@ propnames/from/ccc@1, und, 783B, 38e394b20d58c1df
propnames/from/ea@1, und, 105B, 4bc69f982fa6b2de
propnames/from/gc@1, und, 747B, 2f7ece7581036df2
propnames/from/gcm@1, und, 907B, 43b812154d2d3914
propnames/from/jt@1, und, 131B, b45c742d4b17ceb
propnames/from/lb@1, und, 963B, bb6e2daf75e2057f
propnames/from/sc@1, und, 3640B, d1ed7fca398b05b8
propnames/to/long/linear/GCB@1, und, 151B, 9feae38a09898348
Expand All @@ -4898,6 +4899,7 @@ propnames/to/long/linear/WB@1, und, 245B, 7d725adfd056f4a4
propnames/to/long/linear/bc@1, und, 460B, 98758a587d562ad1
propnames/to/long/linear/ea@1, und, 61B, b4df37d762a5c879
propnames/to/long/linear/gc@1, und, 488B, 4786f3c0d2d639d
propnames/to/long/linear/jt@1, und, 88B, d9b49c75470a1afa
propnames/to/long/linear/lb@1, und, 598B, 6ee04a546e351ffb
propnames/to/long/linear/sc@1, und, 1964B, 9b97b7f85684632c
propnames/to/long/sparse/ccc@1, und, 652B, 440a07537c221a20
Expand All @@ -4908,6 +4910,7 @@ propnames/to/short/linear/WB@1, und, 111B, 625b4965d4282611
propnames/to/short/linear/bc@1, und, 103B, 85ea5db229b1eaba
propnames/to/short/linear/ea@1, und, 24B, 9dcf5f0ed5697f5b
propnames/to/short/linear/gc@1, und, 125B, a6da6a4499b7361b
propnames/to/short/linear/jt@1, und, 23B, 4f7c0d697e2b792f
propnames/to/short/linear/lb@1, und, 199B, 808bb5403b659e4
propnames/to/short/linear4/sc@1, und, 806B, d488da3356b27392
propnames/to/short/sparse/ccc@1, und, 478B, aa23b3caa16eae5e
Expand Down Expand Up @@ -5071,6 +5074,7 @@ props/exemplarchars/punctuation@1, tr, 123B, 2e7906785ab47589
props/exemplarchars/punctuation@1, und, 59B, 42e553f11527bac0
props/gc@1, und, 17012B, 1d6406352436488b
props/graph@1, und, 5707B, 2fd03ad84767b721
props/jt@1, und, 6915B, 877aaf1128f9f651
props/lb@1, und, 14856B, 9add7e1b9033c67d
props/nfcinert@1, und, 7211B, f1234f4fe31e6a0d
props/nfdinert@1, und, 3267B, 20cfe23fc3115a5d
Expand Down
4 changes: 2 additions & 2 deletions utils/zerovec/derive/examples/derives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use zerovec::ule::AsULE;
use zerovec::ule::EncodeAsVarULE;
use zerovec::*;

#[repr(packed)]
#[repr(C, packed)]
#[derive(ule::ULE, Copy, Clone)]
pub struct FooULE {
a: u8,
Expand Down Expand Up @@ -40,7 +40,7 @@ impl AsULE for Foo {
}
}

#[repr(packed)]
#[repr(C, packed)]
#[derive(ule::VarULE)]
pub struct RelationULE {
/// This maps to (AndOr, Polarity, Operand),
Expand Down
2 changes: 1 addition & 1 deletion utils/zerovec/derive/src/make_ule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ fn make_ule_enum_impl(
attrs: ZeroVecAttrs,
) -> TokenStream2 {
// We could support more int reprs in the future if needed
if !utils::has_valid_repr(&input.attrs, |r| r == "u8") {
if !utils::ReprInfo::compute(&input.attrs).u8 {
return Error::new(
input.span(),
"#[make_ule] can only be applied to #[repr(u8)] enums",
Expand Down
4 changes: 2 additions & 2 deletions utils/zerovec/derive/src/ule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Error};

pub fn derive_impl(input: &DeriveInput) -> TokenStream2 {
if !utils::has_valid_repr(&input.attrs, |r| r == "packed" || r == "transparent") {
if !utils::ReprInfo::compute(&input.attrs).cpacked_or_transparent() {
return Error::new(
input.span(),
"derive(ULE) must be applied to a #[repr(packed)] or #[repr(transparent)] type",
"derive(ULE) must be applied to a #[repr(C, packed)] or #[repr(transparent)] type",
)
.to_compile_error();
}
Expand Down
42 changes: 33 additions & 9 deletions utils/zerovec/derive/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,38 @@ use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{Attribute, Error, Field, Fields, Ident, Index, Result, Token};

// Check that there are repr attributes satisfying the given predicate
pub fn has_valid_repr(attrs: &[Attribute], predicate: impl Fn(&Ident) -> bool + Copy) -> bool {
attrs.iter().filter(|a| a.path().is_ident("repr")).any(|a| {
a.parse_args::<IdentListAttribute>()
.ok()
.and_then(|s| s.idents.iter().find(|s| predicate(s)).map(|_| ()))
.is_some()
})
#[derive(Default)]
pub struct ReprInfo {
pub c: bool,
pub transparent: bool,
pub u8: bool,
pub packed: bool,
}

impl ReprInfo {
pub fn compute(attrs: &[Attribute]) -> Self {
let mut info = ReprInfo::default();
for attr in attrs.iter().filter(|a| a.path().is_ident("repr")) {
if let Ok(pieces) = attr.parse_args::<IdentListAttribute>() {
for piece in pieces.idents.iter() {
if piece == "C" || piece == "c" {
info.c = true;
} else if piece == "transparent" {
info.transparent = true;
} else if piece == "packed" {
info.packed = true;
} else if piece == "u8" {
info.u8 = true;
}
}
}
}
info
}

pub fn cpacked_or_transparent(self) -> bool {
(self.c && self.packed) || self.transparent
}
}

// An attribute that is a list of idents
Expand Down Expand Up @@ -60,7 +84,7 @@ pub fn repr_for(f: &Fields) -> TokenStream2 {
if f.len() == 1 {
quote!(transparent)
} else {
quote!(packed)
quote!(C, packed)
}
}

Expand Down
4 changes: 2 additions & 2 deletions utils/zerovec/derive/src/varule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub fn derive_impl(
input: &DeriveInput,
custom_varule_validator: Option<TokenStream2>,
) -> TokenStream2 {
if !utils::has_valid_repr(&input.attrs, |r| r == "packed" || r == "transparent") {
if !utils::ReprInfo::compute(&input.attrs).cpacked_or_transparent() {
return Error::new(
input.span(),
"derive(VarULE) must be applied to a #[repr(packed)] or #[repr(transparent)] type",
"derive(VarULE) must be applied to a #[repr(C, packed)] or #[repr(transparent)] type",
)
.to_compile_error();
}
Expand Down
2 changes: 1 addition & 1 deletion utils/zerovec/src/flexzerovec/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use core::ops::Range;
const USIZE_WIDTH: usize = mem::size_of::<usize>();

/// A zero-copy "slice" that efficiently represents `[usize]`.
#[repr(packed)]
#[repr(C, packed)]
pub struct FlexZeroSlice {
// Hard Invariant: 1 <= width <= USIZE_WIDTH (which is target_pointer_width)
// Soft Invariant: width == the width of the largest element
Expand Down
4 changes: 2 additions & 2 deletions utils/zerovec/src/ule/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ use core::{mem, slice};
/// 6. Acknowledge the following note about the equality invariant.
///
/// If the ULE type is a struct only containing other ULE types (or other types which satisfy invariants 1 and 2,
/// like `[u8; N]`), invariants 1 and 2 can be achieved via `#[repr(packed)]` or `#[repr(transparent)]`.
/// like `[u8; N]`), invariants 1 and 2 can be achieved via `#[repr(C, packed)]` or `#[repr(transparent)]`.
///
/// # Equality invariant
///
Expand Down Expand Up @@ -271,7 +271,7 @@ where
/// 7. Acknowledge the following note about the equality invariant.
///
/// If the ULE type is a struct only containing other ULE/VarULE types (or other types which satisfy invariants 1 and 2,
/// like `[u8; N]`), invariants 1 and 2 can be achieved via `#[repr(packed)]` or `#[repr(transparent)]`.
/// like `[u8; N]`), invariants 1 and 2 can be achieved via `#[repr(C, packed)]` or `#[repr(transparent)]`.
///
/// # Equality invariant
///
Expand Down
6 changes: 3 additions & 3 deletions utils/zerovec/src/ule/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use core::mem::{self, MaybeUninit};
// Invariants:
// The MaybeUninit is zeroed when None (bool = false),
// and is valid when Some (bool = true)
#[repr(packed)]
#[repr(C, packed)]
pub struct OptionULE<U>(bool, MaybeUninit<U>);

impl<U: Copy> OptionULE<U> {
Expand Down Expand Up @@ -62,11 +62,11 @@ impl<U: Copy + core::fmt::Debug> core::fmt::Debug for OptionULE<U> {

// Safety (based on the safety checklist on the ULE trait):
// 1. OptionULE does not include any uninitialized or padding bytes.
// (achieved by `#[repr(packed)]` on a struct containing only ULE fields,
// (achieved by `#[repr(C, packed)]` on a struct containing only ULE fields,
// in the context of this impl. The MaybeUninit is valid for all byte sequences, and we only generate
/// zeroed or valid-T byte sequences to fill it)
// 2. OptionULE is aligned to 1 byte.
// (achieved by `#[repr(packed)]` on a struct containing only ULE fields, in the context of this impl)
// (achieved by `#[repr(C, packed)]` on a struct containing only ULE fields, in the context of this impl)
// 3. The impl of validate_byte_slice() returns an error if any byte is not valid.
// 4. The impl of validate_byte_slice() returns an error if there are extra bytes.
// 5. The other ULE methods use the default impl.
Expand Down
6 changes: 3 additions & 3 deletions utils/zerovec/src/ule/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ use core::mem;
macro_rules! tuple_ule {
($name:ident, $len:literal, [ $($t:ident $i:tt),+ ]) => {
#[doc = concat!("ULE type for tuples with ", $len, " elements.")]
#[repr(packed)]
#[repr(C, packed)]
#[allow(clippy::exhaustive_structs)] // stable
pub struct $name<$($t),+>($(pub $t),+);

// Safety (based on the safety checklist on the ULE trait):
// 1. TupleULE does not include any uninitialized or padding bytes.
// (achieved by `#[repr(packed)]` on a struct containing only ULE fields)
// (achieved by `#[repr(C, packed)]` on a struct containing only ULE fields)
// 2. TupleULE is aligned to 1 byte.
// (achieved by `#[repr(packed)]` on a struct containing only ULE fields)
// (achieved by `#[repr(C, packed)]` on a struct containing only ULE fields)
// 3. The impl of validate_byte_slice() returns an error if any byte is not valid.
// 4. The impl of validate_byte_slice() returns an error if there are extra bytes.
// 5. The other ULE methods use the default impl.
Expand Down