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

Syntax error when using multiple cfg attributes #78175

Closed
lamafab opened this issue Oct 21, 2020 · 5 comments
Closed

Syntax error when using multiple cfg attributes #78175

lamafab opened this issue Oct 21, 2020 · 5 comments
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@lamafab
Copy link

lamafab commented Oct 21, 2020

I encountered a weird behavior when using cfg(test) and cfg(not(test)).

I tried this code:

fn does_not_work() -> usize {
    #[cfg(not(test))]
    0

    #[cfg(test)]
    1
}

Results in:

   Compiling playground v0.0.1 (/playground)
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `#`
 --> src/lib.rs:6:5
  |
4 |     0
  |      - expected one of `.`, `;`, `?`, `}`, or an operator
5 | 
6 |     #[cfg(test)]
  |     ^ unexpected token

error: aborting due to previous error

error: could not compile `playground`.

To learn more, run the command again with --verbose.

Workaround

fn does_work() -> usize {
    #[cfg(not(test))]
    return 0; // `return` including a semicolon

    #[cfg(test)]
    1
}

Meta

Rust stable version 1.47.0

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f7f7eb30327396c209b0f358b1a3072b

@lamafab lamafab added the C-bug Category: This is a bug. label Oct 21, 2020
@tesuji
Copy link
Contributor

tesuji commented Oct 21, 2020

This is not a bug: @rustbot modify labels: -C-bug

@rustbot rustbot removed the C-bug Category: This is a bug. label Oct 21, 2020
@lamafab
Copy link
Author

lamafab commented Oct 21, 2020

@lzutao Would you mind clarifying?

@tesuji
Copy link
Contributor

tesuji commented Oct 21, 2020

Disclaimer: I'm not the best person to explain this.

Rust doesn't have whitespace sensitive syntax. This means that your example can be written as

#[cfg(not(test))] 0 #[cfg(test)] 1

Which mean that #[cfg(not(test))] could control not only 0 but also 0 #[cfg(test)] 1.
0 #[cfg(test)] 1 is not a valid syntax.

People often use the code below instead:

fn does_not_work() -> usize {
    #[cfg(not(test))] { 0 }
    #[cfg(test)] { 1 }
}

@LeSeulArtichaut
Copy link
Contributor

The diagnostics could probably be improved however

@camelid camelid added A-attributes Area: Attributes (`#[…]`, `#![…]`) A-libtest Area: `#[test]` / the `test` library A-diagnostics Area: Messages for errors, warnings, and lints D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-confusing Diagnostics: Confusing error or lint that should be reworked. A-parser Area: The parsing of Rust source code to an AST and removed A-libtest Area: `#[test]` / the `test` library labels Oct 21, 2020
@JohnTitor JohnTitor added C-enhancement Category: An issue proposing an enhancement or a PR with one. D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 22, 2020
@fmease
Copy link
Member

fmease commented Feb 29, 2024

Current output:

error: expected `;`, found `#`
 --> src/lib.rs:3:6
  |
2 |     #[cfg(not(test))]
  |     ----------------- only `;` terminated statements or tail expressions are allowed after this attribute
3 |     0
  |      ^ expected `;` here
4 |
5 |     #[cfg(test)]
  |     - unexpected token
  |
help: add `;` here
  |
3 |     0;
  |      +
help: alternatively, consider surrounding the expression with a block
  |
3 |     { 0 }
  |     +   +
help: it seems like you are trying to provide different expressions depending on `cfg`, consider using `if cfg!(..)`
  |
2 ~     if cfg!(not(test)) {
3 ~         0
4 | 
5 ~     } else if cfg!(test) {
6 ~         1
7 +     }
  |

This is thanks to #117988. Closing as fixed.

@fmease fmease closed this as completed Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants