mirror of
https://github.com/openharmony/third_party_rust_memoffset.git
synced 2026-07-19 22:44:17 -04:00
Merge pull request #16 from RalfJung/local_inner_macros
use local_inner_macros
This commit is contained in:
+6
-6
@@ -23,7 +23,7 @@
|
||||
#[cfg(memoffset_maybe_uninit)]
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! let_base_ptr {
|
||||
macro_rules! _memoffset__let_base_ptr {
|
||||
($name:ident, $type:tt) => {
|
||||
// No UB here, and the pointer does not dangle, either.
|
||||
// But we have to make sure that `uninit` lives long enough,
|
||||
@@ -37,7 +37,7 @@ macro_rules! let_base_ptr {
|
||||
#[cfg(not(memoffset_maybe_uninit))]
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! let_base_ptr {
|
||||
macro_rules! _memoffset__let_base_ptr {
|
||||
($name:ident, $type:tt) => {
|
||||
// No UB right here, but we will later offset into a field
|
||||
// of this pointer, and that is UB when the pointer is dangling.
|
||||
@@ -49,7 +49,7 @@ macro_rules! let_base_ptr {
|
||||
/// Deref-coercion protection macro.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! field_check {
|
||||
macro_rules! _memoffset__field_check {
|
||||
($type:tt, $field:tt) => {
|
||||
// Make sure the field actually exists. This line ensures that a
|
||||
// compile-time error is generated if $field is accessed through a
|
||||
@@ -77,13 +77,13 @@ macro_rules! field_check {
|
||||
/// assert_eq!(offset_of!(Foo, b), 4);
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! offset_of {
|
||||
($parent:tt, $field:tt) => {{
|
||||
field_check!($parent, $field);
|
||||
_memoffset__field_check!($parent, $field);
|
||||
|
||||
// Get a base pointer.
|
||||
let_base_ptr!(base_ptr, $parent);
|
||||
_memoffset__let_base_ptr!(base_ptr, $parent);
|
||||
// Get the field address. This is UB because we are creating a reference to
|
||||
// the uninitialized field.
|
||||
#[allow(unused_unsafe)] // for when the macro is used in an unsafe block
|
||||
|
||||
+23
-13
@@ -18,6 +18,16 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
/// Reexport for `local_inner_macros`; see
|
||||
/// <https://doc.rust-lang.org/edition-guide/rust-2018/macros/macro-changes.html#macros-using-local_inner_macros>.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! _memoffset__compile_error {
|
||||
($($inner:tt)*) => {
|
||||
compile_error! { $($inner)* }
|
||||
}
|
||||
}
|
||||
|
||||
/// Produces a range instance representing the sub-slice containing the specified member.
|
||||
///
|
||||
/// This macro provides 2 forms of differing functionalities.
|
||||
@@ -75,13 +85,13 @@
|
||||
/// assert_eq!(0..64, span_of!(Blarg, x ..= y));
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! span_of {
|
||||
(@helper $root:ident, [] ..=) => {
|
||||
compile_error!("Expected a range, found '..='")
|
||||
_memoffset__compile_error!("Expected a range, found '..='")
|
||||
};
|
||||
(@helper $root:ident, [] ..) => {
|
||||
compile_error!("Expected a range, found '..'")
|
||||
_memoffset__compile_error!("Expected a range, found '..'")
|
||||
};
|
||||
// Lots of UB due to taking references to uninitialized fields! But that can currently
|
||||
// not be avoided.
|
||||
@@ -91,40 +101,40 @@ macro_rules! span_of {
|
||||
$root as usize + $crate::mem::size_of_val(&(*$root)))
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, [] ..= $field:tt) => {{
|
||||
field_check!($parent, $field);
|
||||
_memoffset__field_check!($parent, $field);
|
||||
($root as usize,
|
||||
&(*$root).$field as *const _ as usize + $crate::mem::size_of_val(&(*$root).$field))
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, [] .. $field:tt) => {{
|
||||
field_check!($parent, $field);
|
||||
_memoffset__field_check!($parent, $field);
|
||||
($root as usize, &(*$root).$field as *const _ as usize)
|
||||
}};
|
||||
// Explicit begin and end for range.
|
||||
(@helper $root:ident, $parent:tt, # $begin:tt [] ..= $end:tt) => {{
|
||||
field_check!($parent, $begin);
|
||||
field_check!($parent, $end);
|
||||
_memoffset__field_check!($parent, $begin);
|
||||
_memoffset__field_check!($parent, $end);
|
||||
(&(*$root).$begin as *const _ as usize,
|
||||
&(*$root).$end as *const _ as usize + $crate::mem::size_of_val(&(*$root).$end))
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, # $begin:tt [] .. $end:tt) => {{
|
||||
field_check!($parent, $begin);
|
||||
field_check!($parent, $end);
|
||||
_memoffset__field_check!($parent, $begin);
|
||||
_memoffset__field_check!($parent, $end);
|
||||
(&(*$root).$begin as *const _ as usize,
|
||||
&(*$root).$end as *const _ as usize)
|
||||
}};
|
||||
// No explicit end for range.
|
||||
(@helper $root:ident, $parent:tt, # $begin:tt [] ..) => {{
|
||||
field_check!($parent, $begin);
|
||||
_memoffset__field_check!($parent, $begin);
|
||||
(&(*$root).$begin as *const _ as usize,
|
||||
$root as usize + $crate::mem::size_of_val(&*$root))
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, # $begin:tt [] ..=) => {{
|
||||
compile_error!(
|
||||
_memoffset__compile_error!(
|
||||
"Found inclusive range to the end of a struct. Did you mean '..' instead of '..='?")
|
||||
}};
|
||||
// Just one field.
|
||||
(@helper $root:ident, $parent:tt, # $begin:tt []) => {{
|
||||
field_check!($parent, $begin);
|
||||
_memoffset__field_check!($parent, $begin);
|
||||
(&(*$root).$begin as *const _ as usize,
|
||||
&(*$root).$begin as *const _ as usize + $crate::mem::size_of_val(&(*$root).$begin))
|
||||
}};
|
||||
@@ -140,7 +150,7 @@ macro_rules! span_of {
|
||||
($sty:tt, $($exp:tt)+) => ({
|
||||
unsafe {
|
||||
// Get a base pointer.
|
||||
let_base_ptr!(root, $sty);
|
||||
_memoffset__let_base_ptr!(root, $sty);
|
||||
let base = root as usize;
|
||||
let (begin, end) = span_of!(@helper root, $sty, [] $($exp)*);
|
||||
begin-base..end-base
|
||||
|
||||
Reference in New Issue
Block a user