Skip to content

Invocation of feature-gated macros inside #[cfg]-guarded code is not checked. #32648

Closed
@LeoTestard

Description

@LeoTestard

While reading libsyntax code, I came across this piece of code:

impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
    fn visit_mac(&mut self, mac: &ast::Mac) {
        let path = &mac.node.path;
        let name = path.segments.last().unwrap().identifier.name.as_str();

        // Issue 22234: If you add a new case here, make sure to also
        // add code to catch the macro during or after expansion.
        //
        // We still keep this MacroVisitor (rather than *solely*
        // relying on catching cases during or after expansion) to
        // catch uses of these macros within conditionally-compiled
        // code, e.g. `#[cfg]`-guarded functions.

        // [...]
    }

   // [...]
}

The comment clearly states that this visitor (MacroVisitor, called by the driver using syntax::feature_gate::check_macros) is there only to check use of such macros inside #[cfg]-guarded code.

Except that this is not the case:

#[cfg(foo)]
fn pwet() { asm!() }

fn main() {}

This compiles on both stable and nightly. The reason for that is that the call to check_crate_macros occur after the call to strip_unconfigured_items. If we still want to catch those invocations, it should be the opposite, although this may have other implications (a comment above the call to strip_unconfigured_items states that this must come before anything else because of #[cfg_attr], I'm not sure if this is relevant for feature-gate checking).
Otherwise, if we want to allow them, then this whole piece of code is useless and should be removed.
I think a lot of crates use #[cfg] to differenciate between stable and nightly builds, especially crates using syntax extensions. For example, we might want to allow this:

#![cfg_attr(nightly, feature(asm))]

#[cfg(nightly)]      fn main() { unsafe { asm!("") } }
#[cfg(not(nightly))] fn main() {}

(I took asm!() as example here because it's one of the feature-gated macros but others might be more relevant I guess.)

(cc @pnkfelix: This is the weird thing I told you about earlier.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions