Skip to content

Features to support libc #557

Closed
Closed
@joshlf

Description

@joshlf

See also: #1769

Prototyped in rust-lang/libc#3407 and rust-lang/libc#3914. MSRV bump in rust-lang/libc#3924.

There are two approaches we could take: try to support version 0.2 (the current version train) or only try to support 1.0 (the next version train).

Version-agnostic considerations

libc almost never releases breaking changes, so if we were to introduce a dependency on zerocopy 0.7, we would never be able to upgrade that dependency to 0.8. Thus, we have two options:

  • Explicitly mark the feature as unstable (eg, name it unstable-zerocopy)
    • This would cause semver issues even for users who understand the risks
  • Introduce one feature per zerocopy semver train (ie, one for 0.7.X, one for 0.8.X, etc)

The second is the better option. What it would take to support differs by libc version; see the discussion below.

Regardless of version, we will need to be able to support an attribute that instructs our derives to rename zerocopy internally (described in #11). This would allow us to write code like:

#[cfg_attr(feature = "zerocopy_0_7", derive(zerocopy_0_7::FromBytes))]
#[cfg_attr(feature = "zerocopy_0_8", derive(zerocopy_0_8::FromBytes))]
#[zerocopy(crate = "zerocopy_0_7", derive-version = "0.7")]
#[zerocopy(crate = "zerocopy_0_8", derive-version = "0.8")]
struct Foo {
    ...
}

Version 1.0 considerations

libc is currently working on a 1.0 release, which will have a much higher MSRV than 0.2. 0.2's current MSRV makes this very tricky (see the discussion below); simply waiting for 1.0 would allow us to sidestep much of that complexity.

Version 0.2 considerations

Proc macro derive naming and imports

Since the MSRV is 1.13, the "edition" is 2015, in which proc macro derives are imported like so:

#[macro_use]
extern crate zerocopy;

This brings all exported macros into the global macro namespace. There is no way to rename macros at import time.

In order to work around this, we would need to dynamically change the edition. Luckily, zerocopy's MSRV is 1.61, which supports more recent editions. Thus, we know that a user can only depend on libc's zerocopy feature using 1.61 or greater. In libc's build.rs, we could detect the Rust version and, for sufficiently recent versions, emit the --edition 2021 rustc flag.

In libc's source code, we again know that zerocopy is only enabled on recent Rust versions, and thus that the edition is 2021. Thus, we could use more recent edition features under #[cfg(feature = "zerocopy-0-7")].

Depending on multiple crate versions

There are multiple options to support this.

Direct

This depends on libc's MSRV being increased to 1.31.

It was only in Rust 1.31 that it became possible to depend directly on multiple versions of a crate like so:

[dependencies]
foo_01 = { package = "foo", version = "0.1.0" }
foo_02 = { package = "foo", version = "0.2.0" }

Even if the zerocopy features are never used on libc's MSRV of 1.13, the Cargo.toml file still needs to parse on 1.13, which this syntax wouldn't.

Facade crates

This depends on libc's MSRV being increased to 1.30.

If libc increases their MSRV to 1.30 instead of 1.31, we would could use a "facade crate" trick: we could upload a facade crate named zerocopy-0-7 with the following Cargo.toml:

[package]
name = "zerocopy-0-7"
version = "1.0.0"
license = "BSD-2-Clause OR Apache-2.0 OR MIT"
repository = "https://github.com/google/zerocopy"
edition = "2018"

[dependencies]
zerocopy = "0.7.0"
zerocopy-derive = "0.7.0"

...and the following src/lib.rs:

pub use zerocopy::*;
pub use zerocopy_derive::{
    AsBytes as AsBytes_0_7, FromBytes as FromBytes_0_7, FromZeroes as FromZeroes_0_7,
    Unaligned as Unaligned_0_7,
};

We would do the same for other version trains (e.g., 0.8) as they are published.

Metadata

Metadata

Assignees

No one assigned

    Labels

    customer-requestDocuments customer requests.experience-hardThis issue is hard, and requires a lot of experiencegoogle-20%-projectPotential 20% project for a Google employeehelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions