From 050b5022fad9581e33819e2e90492b82ce28276c Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 9 Aug 2022 21:49:28 +0200 Subject: [PATCH 1/2] Add static encoding strings --- crates/objc2-encode/CHANGELOG.md | 3 + crates/objc2-encode/src/encoding.rs | 11 +++ crates/objc2-encode/src/lib.rs | 3 - crates/objc2/src/encode/mod.rs | 75 +++++++++++++++++++ crates/test-ui/src/main.rs | 6 ++ crates/tests/src/test_encode_utils.rs | 24 +++++- .../crates/test_encoding_cstr/Cargo.toml | 26 +++++++ .../expected/apple-aarch64.s | 13 ++++ .../test_encoding_cstr/expected/apple-armv7.s | 14 ++++ .../expected/apple-armv7s.s | 14 ++++ .../test_encoding_cstr/expected/apple-x86.s | 14 ++++ .../expected/apple-x86_64.s | 14 ++++ .../test_encoding_cstr/expected/gnustep-x86.s | 18 +++++ .../expected/gnustep-x86_64.s | 18 +++++ .../crates/test_encoding_cstr/lib.rs | 7 ++ test-ui/ui-ignore/encode_cstr_not_ident.rs | 15 ++++ test-ui/ui-ignore/encode_cstr_too_long.rs | 17 +++++ 17 files changed, 285 insertions(+), 7 deletions(-) create mode 100644 test-assembly/crates/test_encoding_cstr/Cargo.toml create mode 100644 test-assembly/crates/test_encoding_cstr/expected/apple-aarch64.s create mode 100644 test-assembly/crates/test_encoding_cstr/expected/apple-armv7.s create mode 100644 test-assembly/crates/test_encoding_cstr/expected/apple-armv7s.s create mode 100644 test-assembly/crates/test_encoding_cstr/expected/apple-x86.s create mode 100644 test-assembly/crates/test_encoding_cstr/expected/apple-x86_64.s create mode 100644 test-assembly/crates/test_encoding_cstr/expected/gnustep-x86.s create mode 100644 test-assembly/crates/test_encoding_cstr/expected/gnustep-x86_64.s create mode 100644 test-assembly/crates/test_encoding_cstr/lib.rs create mode 100644 test-ui/ui-ignore/encode_cstr_not_ident.rs create mode 100644 test-ui/ui-ignore/encode_cstr_too_long.rs diff --git a/crates/objc2-encode/CHANGELOG.md b/crates/objc2-encode/CHANGELOG.md index d1c6d6f11..16adb218f 100644 --- a/crates/objc2-encode/CHANGELOG.md +++ b/crates/objc2-encode/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## Unreleased - YYYY-MM-DD +### Added +* Added `Encode::ENCODING_CSTR` for statically generating an encoding string. + ## 3.0.0 - 2023-07-31 diff --git a/crates/objc2-encode/src/encoding.rs b/crates/objc2-encode/src/encoding.rs index 0404f5b61..17e556d29 100644 --- a/crates/objc2-encode/src/encoding.rs +++ b/crates/objc2-encode/src/encoding.rs @@ -2,6 +2,7 @@ use core::fmt; use crate::helper::{compare_encodings, Helper, NestingLevel}; use crate::parse::Parser; +use crate::static_str::{static_encoding_str_array, static_encoding_str_len}; use crate::EncodingBox; /// An Objective-C type-encoding. @@ -181,6 +182,16 @@ impl Encoding { } }; + /// TODO + pub const fn static_encoding_str_len(&self) -> usize { + static_encoding_str_len(self, NestingLevel::new()) + } + + /// TODO + pub const fn static_encoding_str_array(&self) -> [u8; LEN] { + static_encoding_str_array(self, NestingLevel::new()) + } + /// Check if one encoding is equivalent to another. /// /// Currently, equivalence testing mostly requires that the encodings are diff --git a/crates/objc2-encode/src/lib.rs b/crates/objc2-encode/src/lib.rs index 1bb1f564e..2c7d5b7ef 100644 --- a/crates/objc2-encode/src/lib.rs +++ b/crates/objc2-encode/src/lib.rs @@ -68,9 +68,6 @@ mod encoding; mod encoding_box; mod helper; mod parse; - -// Will be used at some point when generic constants are available -#[allow(dead_code)] mod static_str; pub use self::encoding::Encoding; diff --git a/crates/objc2/src/encode/mod.rs b/crates/objc2/src/encode/mod.rs index 4cdf1d46c..a935bf10f 100644 --- a/crates/objc2/src/encode/mod.rs +++ b/crates/objc2/src/encode/mod.rs @@ -80,6 +80,7 @@ use core::num::{ }; use core::ptr::NonNull; use core::sync::atomic; +use std::ffi::CStr; // Intentionally not `#[doc(hidden)]` pub mod __unstable; @@ -112,6 +113,8 @@ pub use objc2_encode::{Encoding, EncodingBox, ParseError}; /// passed to Objective-C via. `objc2::msg_send!` their destructor will not be /// called! /// +/// Finally, you must not override [`ENCODING_CSTR`][Self::ENCODING_CSTR]. +/// /// /// # Examples /// @@ -149,6 +152,43 @@ pub use objc2_encode::{Encoding, EncodingBox, ParseError}; pub unsafe trait Encode { /// The Objective-C type-encoding for this type. const ENCODING: Encoding; + + #[doc(hidden)] + const __ENCODING_CSTR_LEN: usize = Self::ENCODING.static_encoding_str_len(); + + #[doc(hidden)] + const __ENCODING_CSTR_ARRAY: [u8; 128] = { + if Self::__ENCODING_CSTR_LEN >= 127 { + panic!("encoding string was too long! The maximum supported length is 1023."); + } + + Self::ENCODING.static_encoding_str_array() + }; + + /// The encoding as a static [`CStr`]. + /// + /// This has the same output as `Encoding::to_string`, but it is created + /// at compile-time instead. + /// + /// The encoding is guaranteed to be a pure ASCII string. + #[cfg(feature = "std")] + const ENCODING_CSTR: &'static CStr = { + let mut slice: &[u8] = &Self::__ENCODING_CSTR_ARRAY; + // Cut down to desired size (length + 1 for NUL byte) + // Equivalent to: + // slice[0..Self::__ENCODING_CSTR_LEN + 1] + while slice.len() > Self::__ENCODING_CSTR_LEN + 1 { + if let Some(res) = slice.split_last() { + slice = res.1; + } else { + unreachable!(); + } + } + // SAFETY: `static_encoding_str_array` is guaranteed to not contain + // any NULL bytes (the only place those could appear would be in a + // struct or union name, and that case is checked). + unsafe { CStr::from_bytes_with_nul_unchecked(slice) } + }; } /// Types whoose references has an Objective-C type-encoding. @@ -768,4 +808,39 @@ mod tests { impls_encode(my_fn3 as extern "C" fn(_) -> _); impls_encode(my_fn4 as extern "C" fn(_, _) -> _); } + + #[test] + #[cfg(feature = "std")] + fn test_cstr_simple() { + assert_eq!(i8::__ENCODING_CSTR_LEN, 1); + + let mut array = [0; 128]; + array[0] = b'c'; + assert_eq!(i8::__ENCODING_CSTR_ARRAY, array); + + let cstr = CStr::from_bytes_with_nul(b"c\0").unwrap(); + assert_eq!(i8::ENCODING_CSTR, cstr); + } + + #[test] + #[cfg(feature = "std")] + fn test_cstr() { + struct X; + + unsafe impl Encode for X { + const ENCODING: Encoding = Encoding::Struct( + "abc", + &[ + Encoding::Union("def", &[Encoding::Char]), + <*const *const i8>::ENCODING, + >::ENCODING, + ::ENCODING, + ], + ); + } + + let s = b"{abc=(def=c)^*A^As^?}\0"; + + assert_eq!(X::ENCODING_CSTR.to_bytes_with_nul(), s); + } } diff --git a/crates/test-ui/src/main.rs b/crates/test-ui/src/main.rs index dcce08f5b..86760b2d8 100644 --- a/crates/test-ui/src/main.rs +++ b/crates/test-ui/src/main.rs @@ -13,8 +13,14 @@ fn main() { let t = trybuild::TestCases::new(); + let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) .join("ui") .join("*.rs"); t.compile_fail(path); + + let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("ui-ignore") + .join("*.rs"); + t.pass(path); } diff --git a/crates/tests/src/test_encode_utils.rs b/crates/tests/src/test_encode_utils.rs index 1892ca559..13a29be95 100644 --- a/crates/tests/src/test_encode_utils.rs +++ b/crates/tests/src/test_encode_utils.rs @@ -20,6 +20,12 @@ unsafe fn assert_encoding(s: *const c_char, e: Encoding) { assert_eq!(e.to_string(), s.trim_start_matches('r')); } +unsafe fn assert_ty(s: *const c_char) { + assert_encoding(s, T::ENCODING); + // To ensure ENCODING_CSTR is implemented correctly + assert_eq!(T::ENCODING_CSTR.to_str().unwrap(), T::ENCODING.to_string()); +} + #[allow(unused)] unsafe fn assert_str(s: *const c_char, expected: T) { let s = CStr::from_ptr(s).to_str().unwrap(); @@ -38,6 +44,16 @@ macro_rules! assert_inner { unsafe { assert_encoding($stat, $expected) }; } }; + (ty $(#[$m:meta])* $stat:ident => $expected:ty) => { + $(#[$m])* + #[test] + fn $stat() { + extern "C" { + static $stat: *const c_char; + } + unsafe { assert_ty::<$expected>($stat) }; + } + }; (str $(#[$m:meta])* $stat:ident => $expected:expr) => { $(#[$m])* #[test] @@ -77,10 +93,10 @@ macro_rules! assert_types { $stat:ident $($should_atomic:ident)? => $type:ident ) => { paste! { - assert_inner!(enc $(#[$m])* [] => <$type>::ENCODING); - assert_inner!(enc $(#[$m])* [] => <*const $type>::ENCODING); - assert_inner!(enc $(#[$m])* [] => <*const *const $type>::ENCODING); - assert_inner!(enc $(#[$m])* [] => <*const *const *const $type>::ENCODING); + assert_inner!(ty $(#[$m])* [] => $type); + assert_inner!(ty $(#[$m])* [] => *const $type); + assert_inner!(ty $(#[$m])* [] => *const *const $type); + assert_inner!(ty $(#[$m])* [] => *const *const *const $type); $(assert_types!(#$should_atomic);)? assert_inner!(enc $(#[$m])* $(#[cfg($should_atomic)])? [] => Encoding::Atomic(&<$type>::ENCODING)); assert_inner!(enc $(#[$m])* $(#[cfg($should_atomic)])? [] => Encoding::Pointer(&Encoding::Atomic(&<$type>::ENCODING))); diff --git a/test-assembly/crates/test_encoding_cstr/Cargo.toml b/test-assembly/crates/test_encoding_cstr/Cargo.toml new file mode 100644 index 000000000..7aaa9f726 --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "test_encoding_cstr" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +path = "lib.rs" + +[dependencies] +objc2-encode = { path = "../../../objc2-encode", default-features = false } + +[features] +default = ["apple", "std"] +std = ["objc2-encode/std"] + +# Runtime +apple = [] +gnustep-1-7 = [] +gnustep-1-8 = ["gnustep-1-7"] +gnustep-1-9 = ["gnustep-1-8"] +gnustep-2-0 = ["gnustep-1-9"] +gnustep-2-1 = ["gnustep-2-0"] + +# Hack +assembly-features = ["std"] diff --git a/test-assembly/crates/test_encoding_cstr/expected/apple-aarch64.s b/test-assembly/crates/test_encoding_cstr/expected/apple-aarch64.s new file mode 100644 index 000000000..987168def --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/expected/apple-aarch64.s @@ -0,0 +1,13 @@ + .section __TEXT,__text,regular,pure_instructions + .section __TEXT,__const +l_anon.a88231c846af3b75605317c1ca346ede.0: + .asciz "c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + .section __DATA,__const + .globl _ENC + .p2align 3 +_ENC: + .quad l_anon.a88231c846af3b75605317c1ca346ede.0 + .asciz "\002\000\000\000\000\000\000" + +.subsections_via_symbols diff --git a/test-assembly/crates/test_encoding_cstr/expected/apple-armv7.s b/test-assembly/crates/test_encoding_cstr/expected/apple-armv7.s new file mode 100644 index 000000000..652d900da --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/expected/apple-armv7.s @@ -0,0 +1,14 @@ + .section __TEXT,__text,regular,pure_instructions + .syntax unified + .section __TEXT,__const +l_anon.a88231c846af3b75605317c1ca346ede.0: + .asciz "c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + .section __DATA,__const + .globl _ENC + .p2align 2 +_ENC: + .long l_anon.a88231c846af3b75605317c1ca346ede.0 + .asciz "\002\000\000" + +.subsections_via_symbols diff --git a/test-assembly/crates/test_encoding_cstr/expected/apple-armv7s.s b/test-assembly/crates/test_encoding_cstr/expected/apple-armv7s.s new file mode 100644 index 000000000..652d900da --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/expected/apple-armv7s.s @@ -0,0 +1,14 @@ + .section __TEXT,__text,regular,pure_instructions + .syntax unified + .section __TEXT,__const +l_anon.a88231c846af3b75605317c1ca346ede.0: + .asciz "c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + .section __DATA,__const + .globl _ENC + .p2align 2 +_ENC: + .long l_anon.a88231c846af3b75605317c1ca346ede.0 + .asciz "\002\000\000" + +.subsections_via_symbols diff --git a/test-assembly/crates/test_encoding_cstr/expected/apple-x86.s b/test-assembly/crates/test_encoding_cstr/expected/apple-x86.s new file mode 100644 index 000000000..ea253c6f6 --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/expected/apple-x86.s @@ -0,0 +1,14 @@ + .section __TEXT,__text,regular,pure_instructions + .intel_syntax noprefix + .section __TEXT,__const +l_anon.a88231c846af3b75605317c1ca346ede.0: + .asciz "c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + .section __DATA,__const + .globl _ENC + .p2align 2 +_ENC: + .long l_anon.a88231c846af3b75605317c1ca346ede.0 + .asciz "\002\000\000" + +.subsections_via_symbols diff --git a/test-assembly/crates/test_encoding_cstr/expected/apple-x86_64.s b/test-assembly/crates/test_encoding_cstr/expected/apple-x86_64.s new file mode 100644 index 000000000..a71ee045e --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/expected/apple-x86_64.s @@ -0,0 +1,14 @@ + .section __TEXT,__text,regular,pure_instructions + .intel_syntax noprefix + .section __TEXT,__const +l_anon.a88231c846af3b75605317c1ca346ede.0: + .asciz "c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + .section __DATA,__const + .globl _ENC + .p2align 3 +_ENC: + .quad l_anon.a88231c846af3b75605317c1ca346ede.0 + .asciz "\002\000\000\000\000\000\000" + +.subsections_via_symbols diff --git a/test-assembly/crates/test_encoding_cstr/expected/gnustep-x86.s b/test-assembly/crates/test_encoding_cstr/expected/gnustep-x86.s new file mode 100644 index 000000000..1505e57a7 --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/expected/gnustep-x86.s @@ -0,0 +1,18 @@ + .text + .intel_syntax noprefix + .type .Lanon.a88231c846af3b75605317c1ca346ede.0,@object + .section .rodata..Lanon.a88231c846af3b75605317c1ca346ede.0,"a",@progbits +.Lanon.a88231c846af3b75605317c1ca346ede.0: + .asciz "c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + .size .Lanon.a88231c846af3b75605317c1ca346ede.0, 128 + + .type ENC,@object + .section .data.rel.ro.ENC,"aw",@progbits + .globl ENC + .p2align 2 +ENC: + .long .Lanon.a88231c846af3b75605317c1ca346ede.0 + .asciz "\002\000\000" + .size ENC, 8 + + .section ".note.GNU-stack","",@progbits diff --git a/test-assembly/crates/test_encoding_cstr/expected/gnustep-x86_64.s b/test-assembly/crates/test_encoding_cstr/expected/gnustep-x86_64.s new file mode 100644 index 000000000..63ad4915d --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/expected/gnustep-x86_64.s @@ -0,0 +1,18 @@ + .text + .intel_syntax noprefix + .type .Lanon.a88231c846af3b75605317c1ca346ede.0,@object + .section .rodata..Lanon.a88231c846af3b75605317c1ca346ede.0,"a",@progbits +.Lanon.a88231c846af3b75605317c1ca346ede.0: + .asciz "c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + .size .Lanon.a88231c846af3b75605317c1ca346ede.0, 128 + + .type ENC,@object + .section .data.rel.ro.ENC,"aw",@progbits + .globl ENC + .p2align 3 +ENC: + .quad .Lanon.a88231c846af3b75605317c1ca346ede.0 + .asciz "\002\000\000\000\000\000\000" + .size ENC, 16 + + .section ".note.GNU-stack","",@progbits diff --git a/test-assembly/crates/test_encoding_cstr/lib.rs b/test-assembly/crates/test_encoding_cstr/lib.rs new file mode 100644 index 000000000..c74ede513 --- /dev/null +++ b/test-assembly/crates/test_encoding_cstr/lib.rs @@ -0,0 +1,7 @@ +//! Test that the encoding string that we output is not full length. +use std::ffi::CStr; + +use objc2_encode::Encode; + +#[no_mangle] +static ENC: &CStr = i8::ENCODING_CSTR; diff --git a/test-ui/ui-ignore/encode_cstr_not_ident.rs b/test-ui/ui-ignore/encode_cstr_not_ident.rs new file mode 100644 index 000000000..0ea52d93d --- /dev/null +++ b/test-ui/ui-ignore/encode_cstr_not_ident.rs @@ -0,0 +1,15 @@ +//! Test that compilation fails when the struct name is invalid. +//! +//! Ideally, this should be tested by `trybuild`, but it doesn't work at the +//! moment (`cargo check` doesn't catch the error). +use objc2::{Encode, Encoding}; + +struct X; + +unsafe impl Encode for X { + const ENCODING: Encoding<'static> = Encoding::Struct("-", &[]); +} + +fn main() { + let _ = X::ENCODING_CSTR; +} diff --git a/test-ui/ui-ignore/encode_cstr_too_long.rs b/test-ui/ui-ignore/encode_cstr_too_long.rs new file mode 100644 index 000000000..08b610fcb --- /dev/null +++ b/test-ui/ui-ignore/encode_cstr_too_long.rs @@ -0,0 +1,17 @@ +//! Test that compilation fails when the encoding is too long. +//! +//! Ideally, this should be tested by `trybuild`, but it doesn't work at the +//! moment (`cargo check` doesn't catch the error). +use objc2::{Encode, Encoding}; + +struct X; + +const S: &str = unsafe { std::str::from_utf8_unchecked(&[b'a'; 1020]) }; + +unsafe impl Encode for X { + const ENCODING: Encoding<'static> = Encoding::Struct(S, &[]); +} + +fn main() { + let _ = X::ENCODING_CSTR; +} From 9c31a419f9f0140f7ae2694d4924cdf76674930a Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 1 Sep 2023 19:39:01 +0200 Subject: [PATCH 2/2] Use static encoding strings --- crates/icrate/src/additions/Foundation/value.rs | 5 ++--- crates/objc2/src/declare/mod.rs | 17 +++++------------ 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/crates/icrate/src/additions/Foundation/value.rs b/crates/icrate/src/additions/Foundation/value.rs index 78a69358d..f2af7c0b4 100644 --- a/crates/icrate/src/additions/Foundation/value.rs +++ b/crates/icrate/src/additions/Foundation/value.rs @@ -1,10 +1,9 @@ #![cfg(feature = "Foundation_NSValue")] -use alloc::string::ToString; use core::fmt; use core::hash; use core::mem::MaybeUninit; use core::str; -use std::ffi::{CStr, CString}; +use std::ffi::CStr; use objc2::encode::Encode; @@ -35,7 +34,7 @@ impl NSValue { /// [`NSPoint`]: crate::Foundation::NSPoint pub fn new(value: T) -> Id { let bytes: NonNull = NonNull::from(&value); - let encoding = CString::new(T::ENCODING.to_string()).unwrap(); + let encoding = T::ENCODING_CSTR; unsafe { Self::initWithBytes_objCType( Self::alloc(), diff --git a/crates/objc2/src/declare/mod.rs b/crates/objc2/src/declare/mod.rs index 97088959f..dba966091 100644 --- a/crates/objc2/src/declare/mod.rs +++ b/crates/objc2/src/declare/mod.rs @@ -124,7 +124,7 @@ mod ivar_encode; mod ivar_forwarding_impls; use alloc::format; -use alloc::string::ToString; +use core::ffi::CStr; use core::mem; use core::mem::ManuallyDrop; use core::ptr; @@ -550,17 +550,11 @@ impl ClassBuilder { /// happens if there already was an ivar with that name. pub fn add_ivar(&mut self, name: &str) { // SAFETY: The encoding is correct - unsafe { self.add_ivar_inner::(name, &T::ENCODING) } + unsafe { self.add_ivar_inner::(name, &T::ENCODING_CSTR) } } // Monomorphized version - unsafe fn add_ivar_inner_mono( - &mut self, - name: &str, - size: usize, - align: u8, - encoding: &Encoding, - ) { + unsafe fn add_ivar_inner_mono(&mut self, name: &str, size: usize, align: u8, encoding: &CStr) { // `class_addIvar` sadly doesn't check this for us. // // We must _always_ do the check, since there is no way for the user @@ -575,7 +569,6 @@ impl ClassBuilder { } let c_name = CString::new(name).unwrap(); - let encoding = CString::new(encoding.to_string()).unwrap(); let success = Bool::from_raw(unsafe { ffi::class_addIvar( self.as_mut_ptr(), @@ -588,7 +581,7 @@ impl ClassBuilder { assert!(success.as_bool(), "failed to add ivar {name}"); } - unsafe fn add_ivar_inner(&mut self, name: &str, encoding: &Encoding) { + unsafe fn add_ivar_inner(&mut self, name: &str, encoding: &CStr) { unsafe { self.add_ivar_inner_mono(name, mem::size_of::(), T::LOG2_ALIGNMENT, encoding) } } @@ -600,7 +593,7 @@ impl ClassBuilder { /// Same as [`ClassBuilder::add_ivar`]. pub fn add_static_ivar(&mut self) { // SAFETY: The encoding is correct - unsafe { self.add_ivar_inner::(T::NAME, &T::Type::ENCODING) } + unsafe { self.add_ivar_inner::(T::NAME, &T::Type::ENCODING_CSTR) } } /// Adds the given protocol to self.