Skip to content

Commit 37da140

Browse files
authored
Make exported macros hygienic (#1535)
Also add some tests to make sure that they stay hygienic.
1 parent 7f6024b commit 37da140

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

src/cstr.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ macro_rules! cstr {
3636
// We don't use std's `CStr::from_bytes_with_nul`; as of this writing,
3737
// that function isn't defined as `#[inline]` in std and doesn't
3838
// constant-fold away.
39-
assert!(
40-
!$str.bytes().any(|b| b == b'\0'),
39+
::core::assert!(
40+
!::core::iter::Iterator::any(&mut ::core::primitive::str::bytes($str), |b| b == b'\0'),
4141
"cstr argument contains embedded NUL bytes",
4242
);
4343

@@ -51,7 +51,9 @@ macro_rules! cstr {
5151
// contain embedded NULs above, and we append or own NUL terminator
5252
// here.
5353
unsafe {
54-
$crate::ffi::CStr::from_bytes_with_nul_unchecked(concat!($str, "\0").as_bytes())
54+
$crate::ffi::CStr::from_bytes_with_nul_unchecked(
55+
::core::concat!($str, "\0").as_bytes(),
56+
)
5557
}
5658
}
5759
}};
@@ -83,4 +85,25 @@ mod tests {
8385
fn test_invalid_empty_cstr() {
8486
let _ = cstr!("\0");
8587
}
88+
89+
#[no_implicit_prelude]
90+
mod hygiene {
91+
#[allow(unused_macros)]
92+
#[test]
93+
fn macro_hygiene() {
94+
macro_rules! assert {
95+
($($tt:tt)*) => {
96+
::core::panic!("cstr! called the wrong assert! macro");
97+
};
98+
}
99+
macro_rules! concat {
100+
($($tt:tt)*) => {{
101+
let v: &str = ::core::panic!("cstr! called the wrong concat! macro");
102+
v
103+
}};
104+
}
105+
106+
let _ = cstr!("foo");
107+
}
108+
}
86109
}

src/net/send_recv/msg.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ macro_rules! cmsg_space {
6868
};
6969
(TxTime($len:expr)) => {
7070
$crate::net::__cmsg_space(
71-
$len * ::core::mem::size_of::<u64>(),
71+
$len * ::core::mem::size_of::<::core::primitive::u64>(),
7272
)
7373
};
7474

@@ -101,15 +101,15 @@ macro_rules! cmsg_aligned_space {
101101
};
102102
(TxTime($len:expr)) => {
103103
$crate::net::__cmsg_aligned_space(
104-
$len * ::core::mem::size_of::<u64>(),
104+
$len * ::core::mem::size_of::<::core::primitive::u64>(),
105105
)
106106
};
107107

108108
// Combo Rules
109109
($firstid:ident($firstex:expr), $($restid:ident($restex:expr)),*) => {{
110-
let sum = cmsg_aligned_space!($firstid($firstex));
110+
let sum = $crate::cmsg_aligned_space!($firstid($firstex));
111111
$(
112-
let sum = sum + cmsg_aligned_space!($restid($restex));
112+
let sum = sum + $crate::cmsg_aligned_space!($restid($restex));
113113
)*
114114
sum
115115
}};
@@ -985,3 +985,42 @@ mod messages {
985985

986986
impl FusedIterator for Messages<'_> {}
987987
}
988+
989+
#[cfg(test)]
990+
mod tests {
991+
#[no_implicit_prelude]
992+
mod hygiene {
993+
#[allow(unused_macros)]
994+
#[test]
995+
fn macro_hygiene() {
996+
// This `u64` is `!Sized`, so `cmsg_space!` will fail if it tries to get its size with
997+
// `size_of()`.
998+
#[allow(dead_code, non_camel_case_types)]
999+
struct u64([u8]);
1000+
1001+
// Ensure that when `cmsg*_space!` calls itself recursively, it really calls itself and
1002+
// not these macros.
1003+
macro_rules! cmsg_space {
1004+
($($tt:tt)*) => {{
1005+
let v: usize = ::core::panic!("Wrong cmsg_space! macro called");
1006+
v
1007+
}};
1008+
}
1009+
macro_rules! cmsg_aligned_space {
1010+
($($tt:tt)*) => {{
1011+
let v: usize = ::core::panic!("Wrong cmsg_aligned_space! macro called");
1012+
v
1013+
}};
1014+
}
1015+
1016+
crate::cmsg_space!(ScmRights(1));
1017+
crate::cmsg_space!(TxTime(1));
1018+
#[cfg(linux_kernel)]
1019+
{
1020+
crate::cmsg_space!(ScmCredentials(1));
1021+
crate::cmsg_space!(ScmRights(1), ScmCredentials(1), TxTime(1));
1022+
crate::cmsg_aligned_space!(ScmRights(1), ScmCredentials(1), TxTime(1));
1023+
}
1024+
}
1025+
}
1026+
}

0 commit comments

Comments
 (0)