Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
SteveLauC opened this issue Mar 21, 2025 · 4 comments
Closed

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

SteveLauC opened this issue Mar 21, 2025 · 4 comments

Comments

@SteveLauC
Copy link
Member

$ 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;
    }
    }

@SteveLauC SteveLauC changed the title The feature! does not work when encountering cfg_if!() The feature! macro does not work when encountering cfg_if!() Mar 21, 2025
@SteveLauC
Copy link
Member Author

SteveLauC commented Mar 21, 2025

I am going to allow this warning for now to make #2610's CI pass, but we need a solution for this

@Berrysoft
Copy link

Maybe just wait for rustc to fix: rust-lang/rust#138779

@SteveLauC
Copy link
Member Author

Maybe just wait for rustc to fix: rust-lang/rust#138779

Yeah, thanks for letting me know this! :)

@SteveLauC
Copy link
Member Author

Close as this has been fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants