From db5f12b5cf0d84276a640f9bd4b14f62ff2e7953 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Mon, 10 Oct 2022 01:50:18 -0300 Subject: [PATCH 1/8] Added char support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shamelessly copied the implementation from `const_format`(one of my crates) 👀 --- Cargo.toml | 3 + src/fmt.rs | 2 + src/fmt/char_formatting.rs | 152 +++++++++++++++++++++++++++++++ src/fmt/char_formatting/tests.rs | 93 +++++++++++++++++++ src/fmt_impls/basic_fmt_impls.rs | 7 +- src/lib.rs | 2 +- src/utils.rs | 19 ++++ src/utils/utils_tests.rs | 33 +++++++ 8 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 src/fmt/char_formatting.rs create mode 100644 src/fmt/char_formatting/tests.rs create mode 100644 src/utils/utils_tests.rs diff --git a/Cargo.toml b/Cargo.toml index f3fa0d2..f87d49a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,9 @@ version = "=0.2.0" path = "./const_panic_proc_macros/" optional = true +[dev-dependencies.arrayvec] +version = "0.7" + [dev-dependencies.rand] version = "0.8.4" default_features = false diff --git a/src/fmt.rs b/src/fmt.rs index ebc62d6..fcfd92f 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -21,6 +21,8 @@ mod non_basic_fmt; #[cfg(feature = "non_basic")] mod fmt_compressed; +pub mod char_formatting; + #[cfg(feature = "non_basic")] pub use self::{fmt_compressed::PackedFmtArg, non_basic_fmt::*}; diff --git a/src/fmt/char_formatting.rs b/src/fmt/char_formatting.rs new file mode 100644 index 0000000..5fdc987 --- /dev/null +++ b/src/fmt/char_formatting.rs @@ -0,0 +1,152 @@ +//! `char`-formatted related items + +use crate::{ + fmt::{FmtArg, FmtKind}, + fmt_impls::basic_fmt_impls::primitive_static_panicfmt, + panic_val::{PanicVal, PanicVariant}, + utils::{string_cap, PreFmtString}, +}; + +#[cfg(all(test, not(miri)))] +mod tests; + +impl PanicVal<'_> { + /// Constructs a `PanicVal` from a `char`. + pub const fn from_char(c: char, fmtarg: FmtArg) -> Self { + let (len, arr) = match fmtarg.fmt_kind { + FmtKind::Display => { + let (arr, len) = char_to_utf8(c); + ( + crate::utils::extend_byte_array::<4, { string_cap::PREFMT }>(arr), + len as u8, + ) + } + FmtKind::Debug => { + let fmtchar = char_to_debug(c); + ( + crate::utils::extend_byte_array(fmtchar.encoded), + fmtchar.len, + ) + } + }; + // SAFETY: + // char_to_utf8 is exhaustively tested in the tests module. + // char_to_debug is exhaustively tested in the tests module. + // extend_byte_array is also tested for smaller/equal/larger input arrays. + let prefmt = unsafe { PreFmtString::new(arr, len) }; + PanicVal { + var: PanicVariant::PreFmt(prefmt), + } + } +} + +primitive_static_panicfmt! { + fn[](&self: char, fmtarg) { + PanicVal::from_char(*self.0, fmtarg) + } +} + +/// Converts 0..=0xF to its ascii representation of '0'..='9' and 'A'..='F' +#[inline] +const fn hex_as_ascii(n: u8) -> u8 { + if n < 10 { + n + b'0' + } else { + n - 10 + b'A' + } +} + +#[cfg(any(test, feature = "fmt"))] +pub(crate) const fn char_debug_len(c: char) -> usize { + let inner = match c { + '\t' | '\r' | '\n' | '\\' | '\'' | '\"' => 2, + '\x00'..='\x1F' => 4, + _ => c.len_utf8(), + }; + inner + 2 +} + +const fn char_to_utf8(char: char) -> ([u8; 4], usize) { + let u32 = char as u32; + match u32 { + 0..=127 => ([u32 as u8, 0, 0, 0], 1), + 0x80..=0x7FF => { + let b0 = 0b1100_0000 | (u32 >> 6) as u8; + let b1 = 0b1000_0000 | (u32 & 0b0011_1111) as u8; + ([b0, b1, 0, 0], 2) + } + 0x800..=0xFFFF => { + let b0 = 0b1110_0000 | (u32 >> 12) as u8; + let b1 = 0b1000_0000 | ((u32 >> 6) & 0b0011_1111) as u8; + let b2 = 0b1000_0000 | (u32 & 0b0011_1111) as u8; + ([b0, b1, b2, 0], 3) + } + 0x10000..=u32::MAX => { + let b0 = 0b1111_0000 | (u32 >> 18) as u8; + let b1 = 0b1000_0000 | ((u32 >> 12) & 0b0011_1111) as u8; + let b2 = 0b1000_0000 | ((u32 >> 6) & 0b0011_1111) as u8; + let b3 = 0b1000_0000 | (u32 & 0b0011_1111) as u8; + ([b0, b1, b2, b3], 4) + } + } +} + +/// Display formats a `char` +pub const fn char_to_display(char: char) -> FmtChar { + let ([b0, b1, b2, b3], len) = char_to_utf8(char); + FmtChar { + encoded: [b0, b1, b2, b3, 0, 0, 0, 0, 0, 0, 0, 0], + len: len as u8, + } +} + +/// Debug formats a `char` +pub const fn char_to_debug(c: char) -> FmtChar { + let ([b0, b1, b2, b3], len) = match c { + '\t' => (*br#"\t "#, 2), + '\r' => (*br#"\r "#, 2), + '\n' => (*br#"\n "#, 2), + '\\' => (*br#"\\ "#, 2), + '\'' => (*br#"\' "#, 2), + '\"' => (*br#"\" "#, 2), + '\x00'..='\x1F' => { + let n = c as u8; + ( + [b'\\', b'x', hex_as_ascii(n >> 4), hex_as_ascii(n & 0b1111)], + 4, + ) + } + _ => char_to_utf8(c), + }; + + let mut encoded = [b'\'', b0, b1, b2, b3, 0, 0, 0, 0, 0, 0, 0]; + encoded[len + 1] = b'\''; + + FmtChar { + encoded, + len: (len as u8) + 2, + } +} + +/// An byte slice with a display/debug formatted `char`. +/// +/// To get the encoded character, you need to do +/// `&fmt_char.encoded()[..fmt_char.len()]`. +#[derive(Copy, Clone)] +pub struct FmtChar { + encoded: [u8; 12], + len: u8, +} + +impl FmtChar { + /// Array which contains the display/debug-formatted `char`, + /// and trailing `0` padding. + pub const fn encoded(&self) -> &[u8; 12] { + &self.encoded + } + + /// The length of the subslice that contains the formatted character. + pub const fn len(&self) -> usize { + self.len as usize + } +} diff --git a/src/fmt/char_formatting/tests.rs b/src/fmt/char_formatting/tests.rs new file mode 100644 index 0000000..c000ed4 --- /dev/null +++ b/src/fmt/char_formatting/tests.rs @@ -0,0 +1,93 @@ +use super::{char_debug_len, char_to_debug, char_to_display, FmtChar}; + +fn as_bytes(fmt: &FmtChar) -> &[u8] { + &fmt.encoded()[..fmt.len()] +} + +#[test] +fn char_to_utf8_encoding_test() { + for c in '\0'..=core::char::MAX { + let mut utf8_std = [0u8; 4]; + let utf8_std = c.encode_utf8(&mut utf8_std); + + let utf8_here = char_to_display(c); + assert_eq!(utf8_std.as_bytes(), as_bytes(&utf8_here)); + } +} + +#[test] +fn char_to_utf8_display_test() { + for c in '\0'..=core::char::MAX { + let mut utf8_std = [0u8; 4]; + let utf8_std = c.encode_utf8(&mut utf8_std); + + let utf8_here = char_to_display(c); + assert_eq!(utf8_std.as_bytes(), as_bytes(&utf8_here)); + } +} + +#[test] +fn char_to_utf8_debug_test() { + let first_escapes = [ + ('\x00', r#"'\x00'"#), + ('\x01', r#"'\x01'"#), + ('\x02', r#"'\x02'"#), + ('\x03', r#"'\x03'"#), + ('\x04', r#"'\x04'"#), + ('\x05', r#"'\x05'"#), + ('\x06', r#"'\x06'"#), + ('\x07', r#"'\x07'"#), + ('\x08', r#"'\x08'"#), + ('\t', r#"'\t'"#), + ('\n', r#"'\n'"#), + ('\x0B', r#"'\x0B'"#), + ('\x0C', r#"'\x0C'"#), + ('\r', r#"'\r'"#), + ('\x0E', r#"'\x0E'"#), + ('\x0F', r#"'\x0F'"#), + ('\x10', r#"'\x10'"#), + ('\x11', r#"'\x11'"#), + ('\x12', r#"'\x12'"#), + ('\x13', r#"'\x13'"#), + ('\x14', r#"'\x14'"#), + ('\x15', r#"'\x15'"#), + ('\x16', r#"'\x16'"#), + ('\x17', r#"'\x17'"#), + ('\x18', r#"'\x18'"#), + ('\x19', r#"'\x19'"#), + ('\x1A', r#"'\x1A'"#), + ('\x1B', r#"'\x1B'"#), + ('\x1C', r#"'\x1C'"#), + ('\x1D', r#"'\x1D'"#), + ('\x1E', r#"'\x1E'"#), + ('\x1F', r#"'\x1F'"#), + ]; + + for (c, expected) in first_escapes.iter().copied() { + let utf8_here = char_to_debug(c); + assert_eq!(expected.as_bytes(), as_bytes(&utf8_here), "{:?}", c); + assert_eq!(expected.len(), char_debug_len(c), "{:?}", c); + } + + let other_escapes = [('\'', r#"'\''"#), ('\"', r#"'\"'"#), ('\\', r#"'\\'"#)]; + + let mut buffer = arrayvec::ArrayString::<12>::new(); + for c in '\x20'..=core::char::MAX { + let utf8_here = char_to_debug(c); + + if let Some((_, expected)) = Some(c) + .filter(|c| *c <= '\x7F') + .and_then(|c| other_escapes.iter().copied().find(|x| x.0 == c)) + { + assert_eq!(expected.as_bytes(), as_bytes(&utf8_here), "{:?}", c); + assert_eq!(expected.len(), char_debug_len(c), "{:?}", c); + } else { + buffer.clear(); + buffer.push('\''); + buffer.push(c); + buffer.push('\''); + assert_eq!(buffer.as_bytes(), as_bytes(&utf8_here), "{:?}", c); + assert_eq!(buffer.len(), char_debug_len(c), "{:?}", c); + } + } +} diff --git a/src/fmt_impls/basic_fmt_impls.rs b/src/fmt_impls/basic_fmt_impls.rs index 727ed17..e0bfd56 100644 --- a/src/fmt_impls/basic_fmt_impls.rs +++ b/src/fmt_impls/basic_fmt_impls.rs @@ -10,7 +10,7 @@ macro_rules! primitive_static_panicfmt { $($content:tt)* } ) => { - impl<$($impl)*> PanicFmt for $ty { + impl<$($impl)*> crate::PanicFmt for $ty { type This = Self; type Kind = crate::fmt::IsStdType; const PV_COUNT: usize = 1; @@ -20,7 +20,7 @@ macro_rules! primitive_static_panicfmt { #[doc = concat!( "Converts this `", stringify!($ty), "` to a single-element `PanicVal` array." )] - pub const fn to_panicvals($self, $f: FmtArg) -> [PanicVal<'static>; 1] { + pub const fn to_panicvals($self, $f: crate::FmtArg) -> [PanicVal<'static>; 1] { [{ $($content)* }] @@ -29,12 +29,13 @@ macro_rules! primitive_static_panicfmt { #[doc = concat!( "Converts this `", stringify!($ty), "` to a `PanicVal`." )] - pub const fn to_panicval($self, $f: FmtArg) -> PanicVal<'static> { + pub const fn to_panicval($self, $f: crate::FmtArg) -> PanicVal<'static> { $($content)* } } } } +pub(crate) use primitive_static_panicfmt; macro_rules! impl_panicfmt_panicval_array { ( diff --git a/src/lib.rs b/src/lib.rs index 7bc3ec1..bb54a01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -245,7 +245,7 @@ mod wrapper; mod fmt_impls { #[macro_use] - mod basic_fmt_impls; + pub(crate) mod basic_fmt_impls; #[macro_use] #[cfg(feature = "non_basic")] diff --git a/src/utils.rs b/src/utils.rs index f95d601..93dc33f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,6 +2,9 @@ use crate::debug_str_fmt::ForEscaping; +#[cfg(test)] +mod utils_tests; + #[cfg(feature = "non_basic")] mod non_basic_utils; @@ -194,3 +197,19 @@ const fn next_char_boundary(ranged: RangedBytes<&[u8]>, mut i: usize) -> usize { } i } + +pub(crate) const fn extend_byte_array( + input: [u8; FROM], +) -> [u8; TO] { + assert!(FROM <= TO); + + let mut out = [0u8; TO]; + + let mut i = 0; + while i < FROM { + out[i] = input[i]; + i += 1; + } + + out +} diff --git a/src/utils/utils_tests.rs b/src/utils/utils_tests.rs new file mode 100644 index 0000000..7356dc6 --- /dev/null +++ b/src/utils/utils_tests.rs @@ -0,0 +1,33 @@ +use super::extend_byte_array; + +#[test] +fn extend_byte_array_eq_gt_tests() { + assert_eq!(extend_byte_array::<0, 1>([]), [0]); + assert_eq!(extend_byte_array::<0, 2>([]), [0, 0]); + + assert_eq!(extend_byte_array::<1, 1>([3]), [3]); + assert_eq!(extend_byte_array::<1, 2>([3]), [3, 0]); + assert_eq!(extend_byte_array::<1, 3>([3]), [3, 0, 0]); + + assert_eq!(extend_byte_array::<2, 2>([3, 5]), [3, 5]); + assert_eq!(extend_byte_array::<2, 3>([3, 5]), [3, 5, 0]); + assert_eq!(extend_byte_array::<2, 4>([3, 5]), [3, 5, 0, 0]); +} + +#[test] +#[should_panic] +fn extend_byte_array_smaller_test_0() { + let _: [u8; 0] = extend_byte_array([1]); +} + +#[test] +#[should_panic] +fn extend_byte_array_smaller_test_1() { + let _: [u8; 1] = extend_byte_array([1, 2]); +} + +#[test] +#[should_panic] +fn extend_byte_array_smaller_test_2() { + let _: [u8; 0] = extend_byte_array([1, 2]); +} From e2ddcb0a93849fcb90d340a2cce496e4e6d2eda1 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Mon, 10 Oct 2022 05:25:51 -0300 Subject: [PATCH 2/8] Added `"rust_1_64"` feature, which enables impls which require newer versions to format. Updated CI config Added `core::str::Utf8Error` formatting (requires `"rust_1_64"` feature) Added formatting tests for char, fixed implementation --- .github/workflows/rust.yml | 14 +- Cargo.toml | 2 + Changelog.md | 1 + README.md | 3 + src/fmt/char_formatting.rs | 22 ++- src/fmt/char_formatting/tests.rs | 2 +- src/fmt_impls/rust_1_64_fmt_impls.rs | 67 +++++++++ src/lib.rs | 6 + src/utils.rs | 39 ++++-- src/utils/utils_1_64_tests.rs | 159 ++++++++++++++++++++++ src/utils/utils_tests.rs | 33 ----- tests/main_test_modules.rs | 5 + tests/main_tests/char_tests.rs | 32 +++++ tests/main_tests/rust_1_64_types_tests.rs | 29 ++++ 14 files changed, 354 insertions(+), 60 deletions(-) create mode 100644 src/fmt_impls/rust_1_64_fmt_impls.rs create mode 100644 src/utils/utils_1_64_tests.rs delete mode 100644 src/utils/utils_tests.rs create mode 100644 tests/main_tests/char_tests.rs create mode 100644 tests/main_tests/rust_1_64_types_tests.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7958573..a293477 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -12,7 +12,19 @@ jobs: strategy: max-parallel: 2 matrix: - rust: [beta, nightly] + rust: [stable, beta, nightly, 1.64.0, 1.57.0] + + - uses: actions/checkout@v2 + - name: ci-1.64 + if: ${{ matrix.rust != '1.57.0' }} + run: | + rustup override set ${{ matrix.rust }} + cargo update + + cd "${{github.workspace}}/" + + cargo test --no-default-features --features "test rust_1_64" + cargo test --no-default-features --features "test __for_konst" steps: - uses: actions/checkout@v2 diff --git a/Cargo.toml b/Cargo.toml index f87d49a..da03c0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,8 @@ features = ["small_rng"] [features] default = ["non_basic"] + +rust_1_64 = [] non_basic = [] docsrs = [] derive = ["const_panic_proc_macros"] diff --git a/Changelog.md b/Changelog.md index 81393f7..c615b25 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ This changelog is a summary of the changes made in each release. # 0.2 + ### 0.2.0 Added `concat_assert` macro. diff --git a/README.md b/README.md index f68064f..794b797 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,9 @@ Enables support for formatting structs, enums, and arrays. Without this feature, you can effectively only format primitive types (custom types can manually implement formatting with more difficulty). +- `"rust_1_64"`(disabled by default): +Enables formatting of additional items that require Rust 1.64.0 to do so. + - `"derive"`(disabled by default): Enables the [`PanicFmt` derive] macro. diff --git a/src/fmt/char_formatting.rs b/src/fmt/char_formatting.rs index 5fdc987..0e80afd 100644 --- a/src/fmt/char_formatting.rs +++ b/src/fmt/char_formatting.rs @@ -4,7 +4,7 @@ use crate::{ fmt::{FmtArg, FmtKind}, fmt_impls::basic_fmt_impls::primitive_static_panicfmt, panic_val::{PanicVal, PanicVariant}, - utils::{string_cap, PreFmtString}, + utils::{string_cap, PreFmtString, StartAndBytes}, }; #[cfg(all(test, not(miri)))] @@ -13,27 +13,21 @@ mod tests; impl PanicVal<'_> { /// Constructs a `PanicVal` from a `char`. pub const fn from_char(c: char, fmtarg: FmtArg) -> Self { - let (len, arr) = match fmtarg.fmt_kind { + let StartAndBytes { start, bytes } = match fmtarg.fmt_kind { FmtKind::Display => { let (arr, len) = char_to_utf8(c); - ( - crate::utils::extend_byte_array::<4, { string_cap::PREFMT }>(arr), - len as u8, - ) + crate::utils::tail_byte_array::<{ string_cap::PREFMT }>(len, &arr) } FmtKind::Debug => { let fmtchar = char_to_debug(c); - ( - crate::utils::extend_byte_array(fmtchar.encoded), - fmtchar.len, - ) + crate::utils::tail_byte_array(fmtchar.len(), &fmtchar.encoded) } }; // SAFETY: // char_to_utf8 is exhaustively tested in the tests module. // char_to_debug is exhaustively tested in the tests module. - // extend_byte_array is also tested for smaller/equal/larger input arrays. - let prefmt = unsafe { PreFmtString::new(arr, len) }; + // tail_byte_array is also tested for smaller/equal/larger input arrays. + let prefmt = unsafe { PreFmtString::new(start, bytes) }; PanicVal { var: PanicVariant::PreFmt(prefmt), } @@ -59,7 +53,7 @@ const fn hex_as_ascii(n: u8) -> u8 { #[cfg(any(test, feature = "fmt"))] pub(crate) const fn char_debug_len(c: char) -> usize { let inner = match c { - '\t' | '\r' | '\n' | '\\' | '\'' | '\"' => 2, + '\t' | '\r' | '\n' | '\\' | '\'' => 2, '\x00'..='\x1F' => 4, _ => c.len_utf8(), }; @@ -108,7 +102,7 @@ pub const fn char_to_debug(c: char) -> FmtChar { '\n' => (*br#"\n "#, 2), '\\' => (*br#"\\ "#, 2), '\'' => (*br#"\' "#, 2), - '\"' => (*br#"\" "#, 2), + '\"' => (*br#"" "#, 1), '\x00'..='\x1F' => { let n = c as u8; ( diff --git a/src/fmt/char_formatting/tests.rs b/src/fmt/char_formatting/tests.rs index c000ed4..b9e6549 100644 --- a/src/fmt/char_formatting/tests.rs +++ b/src/fmt/char_formatting/tests.rs @@ -69,7 +69,7 @@ fn char_to_utf8_debug_test() { assert_eq!(expected.len(), char_debug_len(c), "{:?}", c); } - let other_escapes = [('\'', r#"'\''"#), ('\"', r#"'\"'"#), ('\\', r#"'\\'"#)]; + let other_escapes = [('\'', r#"'\''"#), ('\"', r#"'"'"#), ('\\', r#"'\\'"#)]; let mut buffer = arrayvec::ArrayString::<12>::new(); for c in '\x20'..=core::char::MAX { diff --git a/src/fmt_impls/rust_1_64_fmt_impls.rs b/src/fmt_impls/rust_1_64_fmt_impls.rs new file mode 100644 index 0000000..849aacb --- /dev/null +++ b/src/fmt_impls/rust_1_64_fmt_impls.rs @@ -0,0 +1,67 @@ +use crate::{ + fmt::{FmtArg, FmtKind, PanicFmt}, + PanicVal, StdWrapper, +}; + +use core::str::Utf8Error; + +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_64")))] +impl PanicFmt for Utf8Error { + type This = Self; + type Kind = crate::fmt::IsStdType; + const PV_COUNT: usize = 5; +} + +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_64")))] +impl StdWrapper<&Utf8Error> { + /// Formats a `Utf8Error` (supports both Debug and Display formatting). + pub const fn to_panicvals(self, fmtarg: FmtArg) -> [PanicVal<'static>; Utf8Error::PV_COUNT] { + let this = *self.0; + match fmtarg.fmt_kind { + FmtKind::Display => { + let [pv0, pv1, pv2] = match this.error_len() { + Some(x) => [ + PanicVal::write_str("invalid utf-8 sequence of "), + PanicVal::from_usize(x, fmtarg), + PanicVal::write_str(" bytes "), + ], + None => [ + PanicVal::write_str("incomplete utf-8 byte sequence "), + PanicVal::EMPTY, + PanicVal::EMPTY, + ], + }; + + [ + pv0, + pv1, + pv2, + PanicVal::write_str("from index "), + PanicVal::from_usize(this.valid_up_to(), fmtarg), + ] + } + FmtKind::Debug => { + let [pv0, pv1, pv2] = match this.error_len() { + Some(x) => [ + PanicVal::write_str(", error_len: Some("), + PanicVal::from_usize(x, fmtarg), + PanicVal::write_str(") }"), + ], + None => [ + PanicVal::write_str(", error_len: None }"), + PanicVal::EMPTY, + PanicVal::EMPTY, + ], + }; + + [ + PanicVal::write_str("Utf8Error { valid_up_to: "), + PanicVal::from_usize(this.valid_up_to(), fmtarg), + pv0, + pv1, + pv2, + ] + } + } + } +} diff --git a/src/lib.rs b/src/lib.rs index bb54a01..8c11c8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -170,6 +170,9 @@ //! Without this feature, you can effectively only format primitive types //! (custom types can manually implement formatting with more difficulty). //! +//! - `"rust_1_64"`(disabled by default): +//! Enables formatting of additional items that require Rust 1.64.0 to do so. +//! //! - `"derive"`(disabled by default): //! Enables the [`PanicFmt` derive] macro. //! @@ -247,6 +250,9 @@ mod fmt_impls { #[macro_use] pub(crate) mod basic_fmt_impls; + #[cfg(feature = "rust_1_64")] + mod rust_1_64_fmt_impls; + #[macro_use] #[cfg(feature = "non_basic")] mod option_fmt_impls; diff --git a/src/utils.rs b/src/utils.rs index 93dc33f..d105a39 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,8 +2,8 @@ use crate::debug_str_fmt::ForEscaping; -#[cfg(test)] -mod utils_tests; +#[cfg(feature = "rust_1_64")] +mod utils_1_64_tests; #[cfg(feature = "non_basic")] mod non_basic_utils; @@ -198,18 +198,35 @@ const fn next_char_boundary(ranged: RangedBytes<&[u8]>, mut i: usize) -> usize { i } -pub(crate) const fn extend_byte_array( - input: [u8; FROM], -) -> [u8; TO] { - assert!(FROM <= TO); +#[cfg(feature = "rust_1_64")] +#[cfg_attr(feature = "test", derive(Debug, PartialEq))] +pub(crate) struct StartAndBytes { + pub start: u8, + pub bytes: [u8; LEN], +} + +#[cfg(feature = "rust_1_64")] +#[track_caller] +pub(crate) const fn tail_byte_array( + len: usize, + input: &[u8], +) -> StartAndBytes { + assert!(len <= TO); - let mut out = [0u8; TO]; + let mut bytes = [0u8; TO]; - let mut i = 0; - while i < FROM { - out[i] = input[i]; + let start = TO - len; + let mut i = start; + let mut j = 0; + while j < len { + bytes[i] = input[j]; i += 1; + j += 1; } - out + assert!(start < 256); + StartAndBytes { + start: start as u8, + bytes, + } } diff --git a/src/utils/utils_1_64_tests.rs b/src/utils/utils_1_64_tests.rs new file mode 100644 index 0000000..e155dfe --- /dev/null +++ b/src/utils/utils_1_64_tests.rs @@ -0,0 +1,159 @@ +use super::{tail_byte_array, StartAndBytes}; + +#[test] +fn tail_byte_array_eq_gt_tests() { + assert_eq!( + tail_byte_array::<0>(0, &[3]), + StartAndBytes { + bytes: [], + start: 0 + } + ); + assert_eq!( + tail_byte_array::<0>(0, &[3, 5]), + StartAndBytes { + bytes: [], + start: 0 + } + ); + assert_eq!( + tail_byte_array::<1>(0, &[3, 5]), + StartAndBytes { + bytes: [0], + start: 1 + } + ); + assert_eq!( + tail_byte_array::<1>(1, &[3, 5]), + StartAndBytes { + bytes: [3], + start: 0 + } + ); + assert_eq!( + tail_byte_array::<2>(0, &[3, 5]), + StartAndBytes { + bytes: [0, 0], + start: 2 + } + ); + assert_eq!( + tail_byte_array::<2>(1, &[3, 5]), + StartAndBytes { + bytes: [0, 3], + start: 1 + } + ); + assert_eq!( + tail_byte_array::<2>(2, &[3, 5]), + StartAndBytes { + bytes: [3, 5], + start: 0 + } + ); + + assert_eq!( + tail_byte_array::<1>(0, &[]), + StartAndBytes { + bytes: [0], + start: 1 + } + ); + assert_eq!( + tail_byte_array::<2>(0, &[]), + StartAndBytes { + bytes: [0, 0], + start: 2 + } + ); + + assert_eq!( + tail_byte_array::<1>(1, &[3]), + StartAndBytes { + bytes: [3], + start: 0 + } + ); + assert_eq!( + tail_byte_array::<2>(1, &[3]), + StartAndBytes { + bytes: [0, 3], + start: 1 + } + ); + assert_eq!( + tail_byte_array::<3>(1, &[3]), + StartAndBytes { + bytes: [0, 0, 3], + start: 2 + } + ); + + assert_eq!( + tail_byte_array::<2>(1, &[3, 5]), + StartAndBytes { + bytes: [0, 3], + start: 1 + } + ); + assert_eq!( + tail_byte_array::<3>(1, &[3, 5]), + StartAndBytes { + bytes: [0, 0, 3], + start: 2 + } + ); + assert_eq!( + tail_byte_array::<4>(1, &[3, 5]), + StartAndBytes { + bytes: [0, 0, 0, 3], + start: 3 + } + ); + + assert_eq!( + tail_byte_array::<2>(2, &[3, 5]), + StartAndBytes { + bytes: [3, 5], + start: 0 + } + ); + assert_eq!( + tail_byte_array::<3>(2, &[3, 5]), + StartAndBytes { + bytes: [0, 3, 5], + start: 1 + } + ); + assert_eq!( + tail_byte_array::<4>(2, &[3, 5]), + StartAndBytes { + bytes: [0, 0, 3, 5], + start: 2 + } + ); +} + +#[test] +#[should_panic] +fn tail_byte_array_smaller_test_0() { + let _: StartAndBytes<0> = tail_byte_array(2, &[1]); +} + +#[test] +#[should_panic] +fn tail_byte_array_smaller_test_1() { + let _: StartAndBytes<1> = tail_byte_array(3, &[1, 2]); +} + +#[test] +#[should_panic] +fn tail_byte_array_smaller_test_2() { + let _: StartAndBytes<1> = tail_byte_array(3, &[1, 2, 3]); +} + +#[test] +#[should_panic] +fn tail_byte_array_smaller_test_3() { + let _: StartAndBytes<2> = tail_byte_array(3, &[1, 2, 3, 4, 5, 6]); +} diff --git a/src/utils/utils_tests.rs b/src/utils/utils_tests.rs deleted file mode 100644 index 7356dc6..0000000 --- a/src/utils/utils_tests.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::extend_byte_array; - -#[test] -fn extend_byte_array_eq_gt_tests() { - assert_eq!(extend_byte_array::<0, 1>([]), [0]); - assert_eq!(extend_byte_array::<0, 2>([]), [0, 0]); - - assert_eq!(extend_byte_array::<1, 1>([3]), [3]); - assert_eq!(extend_byte_array::<1, 2>([3]), [3, 0]); - assert_eq!(extend_byte_array::<1, 3>([3]), [3, 0, 0]); - - assert_eq!(extend_byte_array::<2, 2>([3, 5]), [3, 5]); - assert_eq!(extend_byte_array::<2, 3>([3, 5]), [3, 5, 0]); - assert_eq!(extend_byte_array::<2, 4>([3, 5]), [3, 5, 0, 0]); -} - -#[test] -#[should_panic] -fn extend_byte_array_smaller_test_0() { - let _: [u8; 0] = extend_byte_array([1]); -} - -#[test] -#[should_panic] -fn extend_byte_array_smaller_test_1() { - let _: [u8; 1] = extend_byte_array([1, 2]); -} - -#[test] -#[should_panic] -fn extend_byte_array_smaller_test_2() { - let _: [u8; 0] = extend_byte_array([1, 2]); -} diff --git a/tests/main_test_modules.rs b/tests/main_test_modules.rs index 289a627..3c42f22 100644 --- a/tests/main_test_modules.rs +++ b/tests/main_test_modules.rs @@ -14,6 +14,11 @@ mod main_tests { mod assert_tests; + mod char_tests; + + #[cfg(feature = "rust_1_64")] + mod rust_1_64_types_tests; + #[cfg(feature = "non_basic")] mod impl_panicfmt_tests; diff --git a/tests/main_tests/char_tests.rs b/tests/main_tests/char_tests.rs new file mode 100644 index 0000000..adecc86 --- /dev/null +++ b/tests/main_tests/char_tests.rs @@ -0,0 +1,32 @@ +//! There's additional tests in const_panic::fmt::char_formatting::tests. + +use const_panic::{FmtArg, StdWrapper}; + +macro_rules! test_val { + ($value:expr) => ({ + let val = $value; + let display = format!("{}", val); + let debug = if val > '\u{7E}' { + format!("'{}'", val) + } else { + format!("{:?}", val) + }; + assert_eq!( + trunc_fmt!(32; StdWrapper(&val).to_panicvals(FmtArg::DEBUG)), + &*debug, + "debug", + ); + assert_eq!( + trunc_fmt!(32; StdWrapper(&val).to_panicvals(FmtArg::DISPLAY)), + &*display, + "display", + ); + }) +} + +#[test] +fn basic_char_tests() { + for c in (' '..='\u{FFF}').chain([char::MAX]) { + test_val! {c} + } +} diff --git a/tests/main_tests/rust_1_64_types_tests.rs b/tests/main_tests/rust_1_64_types_tests.rs new file mode 100644 index 0000000..f2ab0d2 --- /dev/null +++ b/tests/main_tests/rust_1_64_types_tests.rs @@ -0,0 +1,29 @@ +use const_panic::{FmtArg, StdWrapper}; + +macro_rules! test_val { + ($value:expr) => ({ + let val = $value; + let display = format!("{}", val); + let debug = format!("{:?}", val); + assert_eq!( + trunc_fmt!(1024; StdWrapper(&val).to_panicvals(FmtArg::DEBUG)), + &*debug, + ); + assert_eq!( + trunc_fmt!(1024; StdWrapper(&val).to_panicvals(FmtArg::DISPLAY)), + &*display, + ); + }) +} + +#[test] +fn test_utf8_error() { + let has_no_error_len = std::str::from_utf8(&[0xC2]).unwrap_err(); + assert_eq!(has_no_error_len.error_len(), None); + + let has_error_len = std::str::from_utf8(&[0x80]).unwrap_err(); + has_error_len.error_len().unwrap(); + + test_val!(has_no_error_len); + test_val!(has_error_len); +} From 4873e6b1326e0106c79eb13e62d81ea25cba87fc Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Mon, 10 Oct 2022 15:52:15 -0300 Subject: [PATCH 3/8] Added `char` slice formatting support --- src/slice_stuff.rs | 1 + src/utils.rs | 2 -- tests/main_tests/array_tests.rs | 54 +++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/slice_stuff.rs b/src/slice_stuff.rs index 73887fe..cb2e159 100644 --- a/src/slice_stuff.rs +++ b/src/slice_stuff.rs @@ -121,6 +121,7 @@ impl_panicfmt_array! { (I128, from_slice_i128, i128), (Isize, from_slice_isize, isize), (Bool, from_slice_bool, bool), + (Char, from_slice_char, char), (Str, from_slice_str, &'s str), } diff --git a/src/utils.rs b/src/utils.rs index d105a39..2859e4e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -198,14 +198,12 @@ const fn next_char_boundary(ranged: RangedBytes<&[u8]>, mut i: usize) -> usize { i } -#[cfg(feature = "rust_1_64")] #[cfg_attr(feature = "test", derive(Debug, PartialEq))] pub(crate) struct StartAndBytes { pub start: u8, pub bytes: [u8; LEN], } -#[cfg(feature = "rust_1_64")] #[track_caller] pub(crate) const fn tail_byte_array( len: usize, diff --git a/tests/main_tests/array_tests.rs b/tests/main_tests/array_tests.rs index 13bc361..d07584c 100644 --- a/tests/main_tests/array_tests.rs +++ b/tests/main_tests/array_tests.rs @@ -69,6 +69,60 @@ fn string_test() { r#"["h\nllo", "人ö个"]"# ); } +#[test] +fn char_test() { + assert_eq!(trunc_fmt!(0; ['c'; 0]), r#""#); + assert_eq!(trunc_fmt!(1; ['c'; 0]), r#"["#); + assert_eq!(trunc_fmt!(2; ['c'; 0]), r#"[]"#); + assert_eq!(trunc_fmt!(3; ['c'; 0]), r#"[]"#); + + assert_eq!(trunc_fmt!(0; ['c']), r#""#); + assert_eq!(trunc_fmt!(1; ['c']), r#"["#); + assert_eq!(trunc_fmt!(2; ['c']), r#"["#); + assert_eq!(trunc_fmt!(3; ['c']), r#"["#); + assert_eq!(trunc_fmt!(4; ['c']), r#"['c'"#); + assert_eq!(trunc_fmt!(5; ['c']), r#"['c']"#); + assert_eq!(trunc_fmt!(6; ['c']), r#"['c']"#); + + for (range, expected) in [ + (0..=0, ""), + (1..=3, "["), + (4..=4, "['c'"), + (5..=5, "['c',"), + (6..=11, "['c', "), + (12..=12, r#"['c', '\x01'"#), + (13..=14, r#"['c', '\x01']"#), + ] { + for len in range { + assert_eq!(trunc_fmt!(len; ['c', '\x01']), expected); + } + } + + for (range, expected) in [ + (0..=0, ""), + (1..=3, "["), + (4..=4, "['c'"), + (5..=5, "['c',"), + (6..=9, "['c', "), + (10..=10, r#"['c', 'ö'"#), + (11..=11, r#"['c', 'ö',"#), + (12..=16, r#"['c', 'ö', "#), + (17..=17, r#"['c', 'ö', '人'"#), + (18..=18, r#"['c', 'ö', '人',"#), + (19..=21, r#"['c', 'ö', '人', "#), + (22..=22, r#"['c', 'ö', '人', '_'"#), + (23..=30, r#"['c', 'ö', '人', '_']"#), + ] { + for len in range { + assert_eq!( + trunc_fmt!(len; ['c', 'ö', '人', '_']), + expected, + "len: {}", + len + ); + } + } +} #[test] fn bin_integer_test() { From 3707db636042be07f01aa3d36b95ae0c2fb5ce38 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Mon, 10 Oct 2022 15:55:39 -0300 Subject: [PATCH 4/8] Bumped version to 0.2.5 Updated changelog. --- Cargo.toml | 2 +- Changelog.md | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index da03c0d..01e1cbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "const_panic" -version = "0.2.4" +version = "0.2.5" authors = ["rodrimati1992 "] edition = "2021" license = "Zlib" diff --git a/Changelog.md b/Changelog.md index c615b25..e769eab 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,14 @@ This changelog is a summary of the changes made in each release. # 0.2 +### 0.2.5 + +Added `"rust_1_64"` feature, which enables formatting impls which require newer versions. + +Added `core::str::Utf8Error` formatting (requires `"rust_1_64"` feature) + +Added formatting support for `char` and slices of `char`. + ### 0.2.0 From e6b4d73d1b2aa83a714d428d61b13002d2185208 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Mon, 10 Oct 2022 16:02:12 -0300 Subject: [PATCH 5/8] Small doc fixes --- src/fmt.rs | 4 ++-- src/macros/impl_panicfmt.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fmt.rs b/src/fmt.rs index fcfd92f..5530a67 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -11,7 +11,7 @@ //! - Manually implementing the [`PanicFmt`] trait as described in its docs. //! //! [`PanicFmt` derive]: derive@crate::PanicFmt -//! [`PanicFmt`]: trait@crate::PanicFmt +//! [`PanicFmt`]: trait@crate::fmt::PanicFmt //! [`impl_panicfmt`]: crate::impl_panicfmt //! [`flatten_panicvals`]: crate::flatten_panicvals @@ -108,7 +108,7 @@ use core::marker::PhantomData; /// /// ``` /// [`PanicFmt` derive]: derive@crate::PanicFmt -/// [`PanicFmt`]: trait@crate::PanicFmt +/// [`PanicFmt`]: trait@crate::fmt::PanicFmt /// [`impl_panicfmt`]: crate::impl_panicfmt /// [`flatten_panicvals`]: crate::flatten_panicvals pub trait PanicFmt { diff --git a/src/macros/impl_panicfmt.rs b/src/macros/impl_panicfmt.rs index 13f166a..2d9624b 100644 --- a/src/macros/impl_panicfmt.rs +++ b/src/macros/impl_panicfmt.rs @@ -1,4 +1,4 @@ -/// Implements the [`PanicFmt`](crate::PanicFmt) +/// Implements the [`PanicFmt`](crate::fmt::PanicFmt) /// trait and the `to_panicvals` method it requires. /// /// This macro roughly takes a type definition and a (conditionally required) list of impls, From e3fbe0507f1c0e055fc32170d288c2bb58b11491 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Mon, 10 Oct 2022 16:09:11 -0300 Subject: [PATCH 6/8] Update rust.yml --- .github/workflows/rust.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a293477..4aabc0e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,6 +14,7 @@ jobs: matrix: rust: [stable, beta, nightly, 1.64.0, 1.57.0] + steps: - uses: actions/checkout@v2 - name: ci-1.64 if: ${{ matrix.rust != '1.57.0' }} @@ -26,8 +27,6 @@ jobs: cargo test --no-default-features --features "test rust_1_64" cargo test --no-default-features --features "test __for_konst" - steps: - - uses: actions/checkout@v2 - name: ci-all-versions run: | rustup override set ${{ matrix.rust }} From f6bd73ecdc09610262e847d8a118359284cdb48e Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Mon, 10 Oct 2022 16:18:21 -0300 Subject: [PATCH 7/8] Updated CI config --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4aabc0e..36e2f0b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -25,7 +25,7 @@ jobs: cd "${{github.workspace}}/" cargo test --no-default-features --features "test rust_1_64" - cargo test --no-default-features --features "test __for_konst" + cargo test --no-default-features --features "test rust_1_64 non_basic" - name: ci-all-versions run: | From d432d5639ab1276153e0c90985362c9f4033d2e1 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Mon, 10 Oct 2022 16:49:21 -0300 Subject: [PATCH 8/8] Fixed nightly tests Had to define custom PhantomData clone, because PhantomData's Debug impl outputs the type argument in nightly. --- src/test_utils.rs | 31 ++++++++++++ tests/main_tests/derive_tests.rs | 18 +++---- tests/main_tests/impl_panicfmt_tests.rs | 64 ++++++++++++------------- 3 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/test_utils.rs b/src/test_utils.rs index 9a5d674..90e4a65 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -51,3 +51,34 @@ macro_rules! concat_fmt { } ) } + +// workaround for PhantomData changing to printing type argument +pub struct MyPhantomData(core::marker::PhantomData); + +impl Copy for MyPhantomData {} + +impl Clone for MyPhantomData { + fn clone(&self) -> Self { + *self + } +} + +impl core::fmt::Debug for MyPhantomData { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.write_str("PhantomData") + } +} + +impl crate::PanicFmt for MyPhantomData { + type This = Self; + type Kind = crate::IsCustomType; + const PV_COUNT: usize = 1; +} + +impl MyPhantomData { + pub const NEW: Self = Self(core::marker::PhantomData); + + pub const fn to_panicvals(self, _: crate::FmtArg) -> [crate::PanicVal<'static>; 1] { + [crate::PanicVal::write_str("PhantomData")] + } +} diff --git a/tests/main_tests/derive_tests.rs b/tests/main_tests/derive_tests.rs index 413aef6..1526bcb 100644 --- a/tests/main_tests/derive_tests.rs +++ b/tests/main_tests/derive_tests.rs @@ -1,6 +1,6 @@ use const_panic::{FmtArg, PanicFmt}; -use core::marker::PhantomData; +use const_panic::test_utils::MyPhantomData; macro_rules! fmt_flatten { ($($args:tt)*) => ( @@ -181,7 +181,7 @@ fn ignored_generic_params_formatting() { { use $module::IgnoredGenericParams as IGP; - let foo = IGP(&3, PhantomData, PhantomData); + let foo = IGP(&3, MyPhantomData::NEW, MyPhantomData::NEW); assert_eq!( fmt_flatten!(FmtArg::DEBUG; IGP => foo), @@ -203,8 +203,8 @@ mod implicit_gpi { #[pfmt(ignore(A, B))] pub struct IgnoredGenericParams<'a, A, B, const X: u32, const Y: char>( pub &'a u32, - pub PhantomData, - pub PhantomData, + pub MyPhantomData, + pub MyPhantomData, ); } @@ -215,8 +215,8 @@ mod explicit_gpi { #[pfmt(ignore(A = u32, B = u64, X = 100, Y = '_'))] pub struct IgnoredGenericParams<'a, A, B, const X: u32, const Y: char>( pub &'a u32, - pub PhantomData, - pub PhantomData, + pub MyPhantomData, + pub MyPhantomData, ); } @@ -231,7 +231,7 @@ fn ignored_generic_params_and_impl_formatting() { (IgnoredAndImpl); ($ty:path) => { - let foo = $ty(&3, PhantomData, PhantomData); + let foo = $ty(&3, MyPhantomData::NEW, MyPhantomData::NEW); assert_eq!( fmt_flatten!(FmtArg::DEBUG; $ty => foo), @@ -253,6 +253,6 @@ fn ignored_generic_params_and_impl_formatting() { #[pfmt(impl<'b, G, const H: u32, const I: char> IgnoredAndImpl<'b, G, u32, H, I>)] pub struct IgnoredAndImpl<'a, A, B, const X: u32, const Y: char>( pub &'a u32, - pub PhantomData, - pub PhantomData, + pub MyPhantomData, + pub MyPhantomData, ); diff --git a/tests/main_tests/impl_panicfmt_tests.rs b/tests/main_tests/impl_panicfmt_tests.rs index 40ad927..9953dd8 100644 --- a/tests/main_tests/impl_panicfmt_tests.rs +++ b/tests/main_tests/impl_panicfmt_tests.rs @@ -1,6 +1,6 @@ use const_panic::FmtArg; -use std::marker::PhantomData; +use const_panic::test_utils::MyPhantomData; #[test] fn struct_formatting() { @@ -178,121 +178,121 @@ fn generic_parsing() { (GenericParsingB6<'_, u32, 0>); ($type_name:path) => { - let foo = $type_name(PhantomData); + let foo = $type_name(MyPhantomData::NEW); assert_eq!(trunc_fmt!(999;FmtArg::DEBUG; foo), *format!("{:?}", foo)); } } } #[derive(Debug)] -struct GenericParsing0<'a>(PhantomData<(&'a (), ())>); +struct GenericParsing0<'a>(MyPhantomData<(&'a (), ())>); #[derive(Debug)] -struct GenericParsing1<'a>(PhantomData<(&'a (), ())>); +struct GenericParsing1<'a>(MyPhantomData<(&'a (), ())>); #[derive(Debug)] -struct GenericParsing2<'a, T>(PhantomData<(&'a (), T)>); +struct GenericParsing2<'a, T>(MyPhantomData<(&'a (), T)>); #[derive(Debug)] -struct GenericParsing3<'a, T>(PhantomData<(&'a (), T)>); +struct GenericParsing3<'a, T>(MyPhantomData<(&'a (), T)>); #[derive(Debug)] -struct GenericParsing4<'a, T, const U: u32>(PhantomData<(&'a (), T)>); +struct GenericParsing4<'a, T, const U: u32>(MyPhantomData<(&'a (), T)>); #[derive(Debug)] -struct GenericParsing5<'a, T, const U: u32>(PhantomData<(&'a (), T)>); +struct GenericParsing5<'a, T, const U: u32>(MyPhantomData<(&'a (), T)>); #[derive(Debug)] -struct GenericParsing6<'a, T, const U: u32>(PhantomData<(&'a (), T)>); +struct GenericParsing6<'a, T, const U: u32>(MyPhantomData<(&'a (), T)>); const_panic::impl_panicfmt! { - struct GenericParsing0<'a,>(PhantomData<(&'a (), ())>); + struct GenericParsing0<'a,>(MyPhantomData<(&'a (), ())>); } const_panic::impl_panicfmt! { - struct GenericParsing1<'a,>(PhantomData<(&'a (), ())>); + struct GenericParsing1<'a,>(MyPhantomData<(&'a (), ())>); } const_panic::impl_panicfmt! { - struct GenericParsing2<'a, ignore T>(PhantomData<(&'a (), T)>); + struct GenericParsing2<'a, ignore T>(MyPhantomData<(&'a (), T)>); } const_panic::impl_panicfmt! { - struct GenericParsing3<'a, ignore T,>(PhantomData<(&'a (), T)>); + struct GenericParsing3<'a, ignore T,>(MyPhantomData<(&'a (), T)>); } const_panic::impl_panicfmt! { - struct GenericParsing4<'a, ignore T, const U: u32>(PhantomData<(&'a (), T)>); + struct GenericParsing4<'a, ignore T, const U: u32>(MyPhantomData<(&'a (), T)>); } const_panic::impl_panicfmt! { - struct GenericParsing5<'a, ignore(PhantomData) T, ignore const U: u32,>( - PhantomData<(&'a (), T)> + struct GenericParsing5<'a, ignore(MyPhantomData) T, ignore const U: u32,>( + MyPhantomData<(&'a (), T)> ); } const_panic::impl_panicfmt! { struct GenericParsing6<'a, ignore T, ignore(2) const U: u32,>( - PhantomData<(&'a (), T)> + MyPhantomData<(&'a (), T)> ); } #[derive(Debug)] -struct GenericParsingB0<'a>(PhantomData<(&'a (), ())>); +struct GenericParsingB0<'a>(MyPhantomData<(&'a (), ())>); #[derive(Debug)] -struct GenericParsingB1<'a>(PhantomData<(&'a (), ())>); +struct GenericParsingB1<'a>(MyPhantomData<(&'a (), ())>); #[derive(Debug)] -struct GenericParsingB2<'a, T: ?Sized>(PhantomData<(&'a (), T)>); +struct GenericParsingB2<'a, T: ?Sized>(MyPhantomData<(&'a (), T)>); #[derive(Debug)] -struct GenericParsingB3<'a, T: ?Sized>(PhantomData<(&'a (), T)>); +struct GenericParsingB3<'a, T: ?Sized>(MyPhantomData<(&'a (), T)>); #[derive(Debug)] -struct GenericParsingB4<'a, T, const U: u32>(PhantomData<(&'a (), T)>); +struct GenericParsingB4<'a, T, const U: u32>(MyPhantomData<(&'a (), T)>); #[derive(Debug)] -struct GenericParsingB5<'a, T, const U: u32>(PhantomData<(&'a (), T)>); +struct GenericParsingB5<'a, T, const U: u32>(MyPhantomData<(&'a (), T)>); #[derive(Debug)] -struct GenericParsingB6<'a, T, const U: u32>(PhantomData<(&'a (), T)>); +struct GenericParsingB6<'a, T, const U: u32>(MyPhantomData<(&'a (), T)>); const_panic::impl_panicfmt! { - struct GenericParsingB0<'a>(PhantomData<(&'a (), ())>); + struct GenericParsingB0<'a>(MyPhantomData<(&'a (), ())>); (impl['a] GenericParsingB0<'a>) } const_panic::impl_panicfmt! { - struct GenericParsingB1<'a>(PhantomData<(&'a (), ())>); + struct GenericParsingB1<'a>(MyPhantomData<(&'a (), ())>); (impl['a] GenericParsingB1<'a,> where[]) } const_panic::impl_panicfmt! { - struct GenericParsingB2<'a, ignore T>(PhantomData<(&'a (), T)>) + struct GenericParsingB2<'a, ignore T>(MyPhantomData<(&'a (), T)>) where[T: ?Sized]; (impl['a, T] GenericParsingB2<'a, T> where[T: ?Sized]) } const_panic::impl_panicfmt! { - struct GenericParsingB3<'a, ignore T,>(PhantomData<(&'a (), T)>) + struct GenericParsingB3<'a, ignore T,>(MyPhantomData<(&'a (), T)>) where[T: ?Sized]; (impl['a, T: ?Sized] GenericParsingB3<'a, T,>) } const_panic::impl_panicfmt! { - struct GenericParsingB4<'a, T, const U: u32>(PhantomData<(&'a (), T)>); + struct GenericParsingB4<'a, T, const U: u32>(MyPhantomData<(&'a (), T)>); (impl['a, const U: u32] GenericParsingB4<'a, u32, U,>) } const_panic::impl_panicfmt! { - struct GenericParsingB5<'a, ignore(PhantomData) T, ignore const U: u32,>( - PhantomData<(&'a (), T)> + struct GenericParsingB5<'a, ignore(MyPhantomData) T, ignore const U: u32,>( + MyPhantomData<(&'a (), T)> ); (impl['a, const U: u32] GenericParsingB5<'a, u32, U>) @@ -300,7 +300,7 @@ const_panic::impl_panicfmt! { const_panic::impl_panicfmt! { struct GenericParsingB6<'a, ignore T, ignore(2) const U: u32,>( - PhantomData<(&'a (), T)> + MyPhantomData<(&'a (), T)> ); (impl['a] GenericParsingB6<'a, u32, 0>)