mirror of
https://github.com/openharmony/third_party_rust_memoffset.git
synced 2026-07-18 12:25:36 -04:00
make the const variant closer to the normal variant (just the offset part is different)
This commit is contained in:
+1
-1
@@ -63,7 +63,7 @@
|
||||
ptr_offset_from,
|
||||
const_ptr_offset_from,
|
||||
const_transmute,
|
||||
const_raw_ptr_deref
|
||||
const_raw_ptr_deref,
|
||||
)
|
||||
)]
|
||||
#![cfg_attr(feature = "unstable_raw", feature(raw_ref_macros))]
|
||||
|
||||
+10
-15
@@ -31,7 +31,9 @@ macro_rules! _memoffset__let_base_ptr {
|
||||
// `let_base_ptr` declares a variable (several, actually)
|
||||
// instead of returning one.
|
||||
let uninit = $crate::mem::MaybeUninit::<$type>::uninit();
|
||||
let $name = uninit.as_ptr();
|
||||
// Transmuting for const-compatibility.
|
||||
#[allow(unused_unsafe)] // for when the macro is used in an unsafe block
|
||||
let $name: *const $type = unsafe { $crate::mem::transmute(&uninit) };
|
||||
};
|
||||
}
|
||||
#[cfg(not(maybe_uninit))]
|
||||
@@ -72,7 +74,7 @@ macro_rules! offset_of {
|
||||
_memoffset__let_base_ptr!(base_ptr, $parent);
|
||||
// Get field pointer.
|
||||
let field_ptr = raw_field!(base_ptr, $parent, $field);
|
||||
// Compute offset.
|
||||
// Compute offset, as integers to make the fewest assumptions.
|
||||
(field_ptr as usize) - (base_ptr as usize)
|
||||
}};
|
||||
}
|
||||
@@ -82,19 +84,12 @@ macro_rules! offset_of {
|
||||
macro_rules! offset_of {
|
||||
($parent:path, $field:tt) => {{
|
||||
// Get a base pointer.
|
||||
// No UB here, and the pointer does not dangle, either.
|
||||
let uninit = $crate::mem::MaybeUninit::<$parent>::uninit();
|
||||
#[allow(unused_unsafe)] // for when the macro is used in an unsafe block
|
||||
unsafe {
|
||||
// This, on the other hand, *is* UB, since we're creating a reference
|
||||
// to uninitialized data.
|
||||
// Unfortunately it's the best we can do at the moment.
|
||||
let base_ptr = $crate::mem::transmute::<_, &$parent>(&uninit) as *const $parent;
|
||||
// Get a field pointer.
|
||||
let field_ptr = raw_field!(base_ptr, $parent, $field);
|
||||
// Compute offset.
|
||||
(field_ptr as *const u8).offset_from(base_ptr as *const u8) as usize
|
||||
}
|
||||
_memoffset__let_base_ptr!(base_ptr, $parent);
|
||||
// Get field pointer.
|
||||
let field_ptr = raw_field!(base_ptr, $parent, $field);
|
||||
// Compute offset, with unstable `offset_from` for const-compatibility.
|
||||
// (Requires the pointers to not dangle, but we already need that for `raw_field!` anyway.)
|
||||
unsafe { (field_ptr as *const u8).offset_from(base_ptr as *const u8) as usize }
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
+17
-22
@@ -31,28 +31,6 @@ macro_rules! _memoffset__field_check {
|
||||
};
|
||||
}
|
||||
|
||||
/// Computes a const raw pointer to the given field of the given base pointer
|
||||
/// to the given parent type.
|
||||
///
|
||||
/// The `base` pointer *must not* be dangling, but it *may* point to
|
||||
/// uninitialized memory.
|
||||
#[cfg(feature = "unstable_raw")] // Correct variant that uses `raw_const!`.
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! raw_field {
|
||||
($base:expr, $parent:path, $field:tt) => {{
|
||||
_memoffset__field_check!($parent, $field);
|
||||
let base_ptr: *const $parent = $base;
|
||||
|
||||
// Get the field address without creating a reference.
|
||||
// Crucially, we know that this will not trigger a deref coercion because
|
||||
// of the `field_check!` we did above.
|
||||
#[allow(unused_unsafe)] // for when the macro is used in an unsafe block
|
||||
unsafe {
|
||||
$crate::ptr::raw_const!((*base_ptr).$field)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Computes a const raw pointer to the given field of the given base pointer
|
||||
/// to the given parent type.
|
||||
///
|
||||
@@ -76,3 +54,20 @@ macro_rules! raw_field {
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable_raw")] // Correct variant that uses `raw_const!`.
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! raw_field {
|
||||
($base:expr, $parent:path, $field:tt) => {{
|
||||
_memoffset__field_check!($parent, $field);
|
||||
let base_ptr: *const $parent = $base;
|
||||
|
||||
// Get the field address without creating a reference.
|
||||
// Crucially, we know that this will not trigger a deref coercion because
|
||||
// of the `field_check!` we did above.
|
||||
#[allow(unused_unsafe)] // for when the macro is used in an unsafe block
|
||||
unsafe {
|
||||
$crate::ptr::raw_const!((*base_ptr).$field)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user