Skip to content

Allow in expression positionΒ #43

@mcclure

Description

@mcclure

Summary:

This macro is currently allowed for statements, but is not allowed as an expression. But, I think it could work as an expression.

Repro:

Try this short program:

use cfg_if::cfg_if;

fn main() {
	let value = cfg_if! {
        if #[cfg(feature = "testfeature")] {
            3 // No `debug` library
        } else {
            4
        }
    };
    println!("Value {}", value);
}

It will fail with this long and vaguely alarming set of messages:

error: macro expansion ignores token `$crate` and any following
  --> /Users/mcc/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-1.0.0/src/lib.rs:79:9
   |
79 |           $crate::cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
   |           ^^^^^^
   | 
  ::: src/main.rs:4:17
   |
4  |       let value = cfg_if! {
   |  _________________-
5  | |         if #[cfg(feature = "testfeature")] {
6  | |             3 // No `debug` library
7  | |         } else {
8  | |             4
9  | |         }
10 | |     };
   | |     -
   | |     |
   | |_____caused by the macro expansion here
   |       help: you might be missing a semicolon here: `;`
   |
   = note: the usage of `cfg_if!` is likely invalid in expression context

error[E0658]: attributes on expressions are experimental
  --> src/main.rs:4:14
   |
4  |       let value = cfg_if! {
   |  _________________^
5  | |         if #[cfg(feature = "testfeature")] {
6  | |             3 // No `debug` library
7  | |         } else {
8  | |             4
9  | |         }
10 | |     };
   | |_____^
   |
   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: removing an expression is not supported in this position
  --> src/main.rs:4:14
   |
4  |       let value = cfg_if! {
   |  _________________^
5  | |         if #[cfg(feature = "testfeature")] {
6  | |             3 // No `debug` library
7  | |         } else {
8  | |             4
9  | |         }
10 | |     };
   | |_____^
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.
error: could not compile `ifcfgtest`

Analysis:

You can actually make this work now by just wrapping an extra {} around the cfg_if expression:

fn main() {
	let value = {cfg_if! {
        if #[cfg(feature = "testfeature")] {
            3 // No `debug` library
        } else {
            4
        }
    }};
    println!("Value {}", value);
}

If you do this, rather than the cfg_if! being an expression, it is a statement inside of a block expression.

Expected behavior:

The cfg_if! macro should just wrap that extra {} around its result itself, thus making it allowed in an expression context.

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