Skip to content

The feature! macro does not work when encountering cfg_if!() #2616

Closed
@SteveLauC

Description

@SteveLauC
$ cargo +nightly --version
cargo 1.86.0-nightly (0e3d73849 2025-02-01)

$ cargo +nightly c --all-features
    Checking nix v0.29.0 (/home/steve/Documents/workspace/nix)
error: unused attribute `<cfg_attr>`
   --> src/macros.rs:9:13
    |
9   |               #[cfg_attr(docsrs, doc(cfg($meta)))]
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
   ::: src/fcntl.rs:235:1
    |
235 | / feature! {
236 | | #![feature = "fs"]
237 | |
238 | | /// open or create a file for reading, writing or executing
...   |
444 | | }
    | |_- in this macro invocation
    |
note: the built-in attribute `<cfg_attr>` will be ignored, since it's applied to the macro invocation `cfg_if::cfg_if`
   --> src/fcntl.rs:293:1
    |
293 | cfg_if::cfg_if! {
    | ^^^^^^^^^^^^^^
note: the lint level is defined here
   --> src/lib.rs:51:9
    |
51  | #![deny(unused)]
    |         ^^^^^^
    = note: `#[deny(unused_attributes)]` implied by `#[deny(unused)]`
    = note: this error originates in the macro `feature` (in Nightly builds, run with -Z macro-backtrace for more info)

error: unused attribute `<cfg_attr>`
   --> src/macros.rs:9:13
    |
9   |               #[cfg_attr(docsrs, doc(cfg($meta)))]
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
   ::: src/sys/signal.rs:387:1
    |
387 | / feature! {
388 | | #![feature = "signal"]
389 | |
390 | | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
...   |
434 | | }
    | |_- in this macro invocation
    |
note: the built-in attribute `<cfg_attr>` will be ignored, since it's applied to the macro invocation `cfg_if`
   --> src/sys/signal.rs:425:1
    |
425 | cfg_if! {
    | ^^^^^^
    = note: this error originates in the macro `feature` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `nix` (lib) due to 2 previous errors

It shows that 2 uses of features!() actually do not work, and it is right:

  1. fcntl.rs

    nix/src/fcntl.rs

    Lines 293 to 413 in e4895d3

    cfg_if::cfg_if! {
    if #[cfg(target_os = "linux")] {
    libc_bitflags! {
    /// Path resolution flags.
    ///
    /// See [path resolution(7)](https://man7.org/linux/man-pages/man7/path_resolution.7.html)
    /// for details of the resolution process.
    pub struct ResolveFlag: libc::c_ulonglong {
    /// Do not permit the path resolution to succeed if any component of
    /// the resolution is not a descendant of the directory indicated by
    /// dirfd. This causes absolute symbolic links (and absolute values of
    /// pathname) to be rejected.
    RESOLVE_BENEATH;
    /// Treat the directory referred to by dirfd as the root directory
    /// while resolving pathname.
    RESOLVE_IN_ROOT;
    /// Disallow all magic-link resolution during path resolution. Magic
    /// links are symbolic link-like objects that are most notably found
    /// in proc(5); examples include `/proc/[pid]/exe` and `/proc/[pid]/fd/*`.
    ///
    /// See symlink(7) for more details.
    RESOLVE_NO_MAGICLINKS;
    /// Disallow resolution of symbolic links during path resolution. This
    /// option implies RESOLVE_NO_MAGICLINKS.
    RESOLVE_NO_SYMLINKS;
    /// Disallow traversal of mount points during path resolution (including
    /// all bind mounts).
    RESOLVE_NO_XDEV;
    }
    }
    /// Specifies how [`openat2()`] should open a pathname.
    ///
    /// # Reference
    ///
    /// * [Linux](https://man7.org/linux/man-pages/man2/open_how.2type.html)
    #[repr(transparent)]
    #[derive(Clone, Copy, Debug)]
    pub struct OpenHow(libc::open_how);
    impl OpenHow {
    /// Create a new zero-filled `open_how`.
    pub fn new() -> Self {
    // safety: according to the man page, open_how MUST be zero-initialized
    // on init so that unknown fields are also zeroed.
    Self(unsafe {
    std::mem::MaybeUninit::zeroed().assume_init()
    })
    }
    /// Set the open flags used to open a file, completely overwriting any
    /// existing flags.
    pub fn flags(mut self, flags: OFlag) -> Self {
    let flags = flags.bits() as libc::c_ulonglong;
    self.0.flags = flags;
    self
    }
    /// Set the file mode new files will be created with, overwriting any
    /// existing flags.
    pub fn mode(mut self, mode: Mode) -> Self {
    let mode = mode.bits() as libc::c_ulonglong;
    self.0.mode = mode;
    self
    }
    /// Set resolve flags, completely overwriting any existing flags.
    ///
    /// See [ResolveFlag] for more detail.
    pub fn resolve(mut self, resolve: ResolveFlag) -> Self {
    let resolve = resolve.bits();
    self.0.resolve = resolve;
    self
    }
    }
    // safety: default isn't derivable because libc::open_how must be zeroed
    impl Default for OpenHow {
    fn default() -> Self {
    Self::new()
    }
    }
    /// Open or create a file for reading, writing or executing.
    ///
    /// `openat2` is an extension of the [`openat`] function that allows the caller
    /// to control how path resolution happens.
    ///
    /// # See also
    ///
    /// [openat2](https://man7.org/linux/man-pages/man2/openat2.2.html)
    pub fn openat2<P: ?Sized + NixPath, Fd: std::os::fd::AsFd>(
    dirfd: Fd,
    path: &P,
    mut how: OpenHow,
    ) -> Result<OwnedFd> {
    use std::os::fd::AsRawFd;
    use std::os::fd::FromRawFd;
    let fd = path.with_nix_path(|cstr| unsafe {
    libc::syscall(
    libc::SYS_openat2,
    dirfd.as_fd().as_raw_fd(),
    cstr.as_ptr(),
    &mut how as *mut OpenHow,
    std::mem::size_of::<libc::open_how>(),
    )
    })? as RawFd;
    Errno::result(fd)?;
    // SAFETY:
    //
    // `openat2(2)` should return a valid owned fd on success
    Ok( unsafe { OwnedFd::from_raw_fd(fd) } )
    }
    }
    }

  2. sys/signal.rs

    nix/src/sys/signal.rs

    Lines 425 to 433 in e4895d3

    cfg_if! {
    if #[cfg(target_os = "redox")] {
    type SaFlags_t = libc::c_ulong;
    } else if #[cfg(target_env = "uclibc")] {
    type SaFlags_t = libc::c_ulong;
    } else {
    type SaFlags_t = libc::c_int;
    }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions