Skip to content

Commit

Permalink
Use stablilized addr_of! macro (#50)
Browse files Browse the repository at this point in the history
Since Rust 1.51.0, support for macro addr_of! has been stabilized[1],
and this provides a way to get a raw pointer without potential UB in
some cases.

Memoffset alreadly uses the feature at the pre-stablilized stage (the
macro was named as raw_const! then). Therefore, switch to use the
stablilized version (and name) if Rust 1.51.0 and above is used,
otherwise use the original fallback version, which works in a less
technically correct way.

[1]: rust-lang/rust#72279

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
  • Loading branch information
fbq committed Mar 8, 2021
1 parent 9111400 commit 576166b
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 16 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@ doc-comment = "0.3"
[features]
default = []
unstable_const = []
unstable_raw = []
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,3 @@ Your crate root: (`lib.rs`/`main.rs`)
```

If you intend to use `offset_of!` inside a `const fn`, also add the `const_fn` compiler feature.

### Raw references ###
Recent nightlies support [a way to create raw pointers](https://github.com/rust-lang/rust/issues/73394) that avoids creating intermediate safe references.
`memoffset` can make use of that feature to avoid what is technically Undefined Behavior.
Use the `unstable_raw` feature to enable this.
3 changes: 3 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ fn main() {
if ac.probe_rustc_version(1, 40) {
println!("cargo:rustc-cfg=doctests");
}
if ac.probe_rustc_version(1, 51) {
println!("cargo:rustc-cfg=raw_ref_macros");
}
}
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
const_raw_ptr_deref,
)
)]
#![cfg_attr(feature = "unstable_raw", feature(raw_ref_macros))]

#[macro_use]
#[cfg(doctests)]
Expand Down
18 changes: 9 additions & 9 deletions src/raw_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

/// `raw_const!`, or just ref-then-cast when that is not available.
#[cfg(feature = "unstable_raw")]
/// `addr_of!`, or just ref-then-cast when that is not available.
#[cfg(raw_ref_macros)]
#[macro_export]
#[doc(hidden)]
macro_rules! _memoffset__raw_const {
macro_rules! _memoffset__addr_of {
($path:expr) => {{
$crate::ptr::raw_const!($path)
$crate::ptr::addr_of!($path)
}};
}
#[cfg(not(feature = "unstable_raw"))]
#[cfg(not(raw_ref_macros))]
#[macro_export]
#[doc(hidden)]
macro_rules! _memoffset__raw_const {
macro_rules! _memoffset__addr_of {
($path:expr) => {{
// This is UB because we create an intermediate reference to uninitialized memory.
// Nothing we can do about that without `raw_const!` though.
// Nothing we can do about that without `addr_of!` though.
&$path as *const _
}};
}
Expand Down Expand Up @@ -88,7 +88,7 @@ macro_rules! raw_field {
// of the field check we did above.
#[allow(unused_unsafe)] // for when the macro is used in an unsafe block
unsafe {
_memoffset__raw_const!((*($base as *const $parent)).$field)
_memoffset__addr_of!((*($base as *const $parent)).$field)
}
}};
}
Expand All @@ -109,7 +109,7 @@ macro_rules! raw_field_tuple {
// of the field check we did above.
#[allow(unused_unsafe)] // for when the macro is used in an unsafe block
unsafe {
_memoffset__raw_const!((*($base as *const $parent)).$field)
_memoffset__addr_of!((*($base as *const $parent)).$field)
}
}};
}

0 comments on commit 576166b

Please sign in to comment.