Bring back upstream support for no_std in Android

As the upstream crate was designed to be no_std (therefore uses core)
and as the Soong targets need to build a dylib (which requires std), the
crate source was being patched to remove the no_std crate attribute.

In turn, as the crate doesn't define a Rust edition, Cargo (and
therefore cargo_embargo) defaults to 2015, which requires explicitly
importing the core crate in no-no_std environments so the code was
further patched to use std modules in place of the corresponding core
modules.

Instead, patch the Cargo.toml to use Rust 2018 (which implicitly imports
core, even in no-no_std) and wrap the no_std in a AOSP-only cfg that we
enable when building Soong targets that include dylib variants.

Enable that cfg from the Android.bp & cargo_embargo.json.

Bug: 324074084
Test: external_updater/updater.sh update --force rust/crates/memoffset
Test: cargo_embargo generate cargo_embargo.json
Test: m libmemoffset libintrusive_collections
Change-Id: Id76df918c0ec89651c4b84402967570e52ae1058
6 files changed
tree: 5fbd5ddd8774ca28a9cc56a7d1fb7d518207542c
  1. .github/
  2. patches/
  3. src/
  4. .cargo_vcs_info.json
  5. .gitignore
  6. Android.bp
  7. build.rs
  8. Cargo.toml
  9. Cargo.toml.orig
  10. cargo_embargo.json
  11. LICENSE
  12. METADATA
  13. MODULE_LICENSE_MIT
  14. OWNERS
  15. README.md
  16. TEST_MAPPING
README.md

memoffset

C-Like offset_of functionality for Rust structs.

Introduces the following macros:

  • offset_of! for obtaining the offset of a member of a struct.
  • offset_of_tuple! for obtaining the offset of a member of a tuple. (Requires Rust 1.20+)
  • offset_of_union! for obtaining the offset of a member of a union.
  • span_of! for obtaining the range that a field, or fields, span.

memoffset works under no_std environments.

Usage

Add the following dependency to your Cargo.toml:

[dependencies]
memoffset = "0.8"

These versions will compile fine with rustc versions greater or equal to 1.19.

Examples

use memoffset::{offset_of, span_of};

#[repr(C, packed)]
struct Foo {
    a: u32,
    b: u32,
    c: [u8; 5],
    d: u32,
}

fn main() {
    assert_eq!(offset_of!(Foo, b), 4);
    assert_eq!(offset_of!(Foo, d), 4+4+5);

    assert_eq!(span_of!(Foo, a),        0..4);
    assert_eq!(span_of!(Foo, a ..  c),  0..8);
    assert_eq!(span_of!(Foo, a ..= c),  0..13);
    assert_eq!(span_of!(Foo, ..= d),    0..17);
    assert_eq!(span_of!(Foo, b ..),     4..17);
}

Usage in constants

memoffset has support for compile-time offset_of! on rust>=1.65, or on older nightly compilers.

Usage on stable Rust

Constant evaluation is automatically enabled and avilable on stable compilers starting with rustc 1.65.

This is an incomplete implementation with one caveat: Due to dependence on #![feature(const_refs_to_cell)], you cannot get the offset of a Cell field in a const-context.

This means that if need to get the offset of a cell, you'll have to remain on nightly for now.

Usage on recent nightlies

If you're using a new-enough nightly and you require the ability to get the offset of a Cell, you'll have to enable the unstable_const cargo feature, as well as enabling const_refs_to_cell in your crate root.

Do note that unstable_const is an unstable feature that is set to be removed in a future version of memoffset.

Cargo.toml:

[dependencies.memoffset]
version = "0.8"
features = ["unstable_const"]

Your crate root: (lib.rs/main.rs)

#![feature(const_refs_to_cell)]

Usage on older nightlies

In order to use it on an older nightly compiler, you must enable the unstable_const crate feature and several compiler features.

Your crate root: (lib.rs/main.rs)

#![feature(const_ptr_offset_from, const_refs_to_cell)]