Skip to content

when $expr is stringify!(...)/concat!(...), #[cfg(feature = $expr)] and #[doc = $expr] don't produce errors #53298

Closed
@ExpHP

Description

@ExpHP

Reproduction

lib.rs

macro_rules! helper {
    ($expr:expr) => {
        #[cfg(feature = $expr)]
        fn foo() {}
    }
}

helper!{concat!("thing")}

This should be an error, as concat!("thing") is not allowed in this position. But instead, the cfg attribute in this example is silently ignored, and fn foo gets compiled.

I tested also with #[doc], hence why the title claims that this applies to "attributes with 'name = $expr'" in general. The previous statement was an overgeneralization. When used on #[doc], this technique apparently sometimes even works!

This is a regression from stable 1.17 to 1.18.

Behavior in various versions

  • rustc 1.01.17: parse error (expected behavior)
  • rustc 1.181.22: ICE
  • rustc 1.23nightly 1.30: silently ignored! 🙈

Output in 1.0–1.17 (expected)

src/lib.rs:3:25: 3:30 error: unexpected token: `concat!("thing")`
src/lib.rs:3         #[cfg(feature = $expr)]
                                     ^~~~~

Output in 1.18–1.22 (ICE)

$ RUST_BACKTRACE=1 cargo +1.18.0 build --example=macro-concat
   Compiling concat v0.1.0 (file:///home/lampam/cpp/throwaway/concat)
error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'no entry found for key', /checkout/src/libcore/option.rs:794
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
      ...
   9: core::option::expect_failed
  10: rustc_resolve::macros::<impl rustc_resolve::Resolver<'a>>::resolve_macro_to_def
  11: rustc_resolve::macros::<impl syntax::ext::base::Resolver for rustc_resolve::Resolver<'a>>::resolve_invoc
  12: syntax::ext::expand::MacroExpander::expand
  13: syntax::ext::expand::MacroExpander::expand_crate
  14: rustc_driver::driver::phase_2_configure_and_expand::{{closure}}
  15: rustc_driver::driver::phase_2_configure_and_expand
  16: rustc_driver::driver::compile_input
  17: rustc_driver::run_compiler
  18: std::panicking::try::do_call
  19: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:98
  20: <F as alloc::boxed::FnBox<A>>::call_box
  21: std::sys::imp::thread::Thread::new::thread_start
             at /checkout/src/liballoc/boxed.rs:650
             at /checkout/src/libstd/sys_common/thread.rs:21
             at /checkout/src/libstd/sys/unix/thread.rs:84
  22: start_thread
  23: clone

Output in 1.23–nightly 1.30 (silently ignored)

   Compiling concat v0.1.0 (file:///home/lampam/cpp/throwaway/concat)
warning: function is never used: `foo`
 --> examples/macro-concat.rs:4:9
  |
4 |         fn foo() {}
  |         ^^^^^^^^
...
8 | helper!{concat!("thing")}
  | ------------------------- in this macro invocation
  |
  = note: #[warn(dead_code)] on by default

Metadata

Metadata

Assignees

Labels

A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions