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

Macro Invocations Behave Questionable Regarding Semicolons #70432

Open
steffahn opened this issue Mar 26, 2020 · 3 comments
Open

Macro Invocations Behave Questionable Regarding Semicolons #70432

steffahn opened this issue Mar 26, 2020 · 3 comments
Labels
A-frontend Area: Compiler frontend (errors, parsing and HIR) A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-parser Area: The parsing of Rust source code to an AST C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@steffahn
Copy link
Member

steffahn commented Mar 26, 2020

Calling Statement Macros with “return values”?

Macros can be used both for expressions and for sequences of statements. The latter being useful to create new definitions (e.g. one or even multiple let clause(s)).

I’m observing that the general rule that expressions ending in a “Block” of type () don’t need a semicolon when used as a statement translates in a weird way to even macros with multiple statements. For example

macro_rules! s {
    ($x:ident) => {
        let $x = 1;
        "hello world"
    }
}

can’t be used as s!{x}. However s!{x}; does work (as does s!(x);). I’m questioning how sensible it is to support these kind of macros since they have some kind of “return value”, whose type even is relevant for if they need a trailing ;, while the “return value” cannot actually in any way (that I can think of) be retrieved.

A way nicer approach at resolving the non-working s!{x} is of course to change the macro:

macro_rules! s {
    ($x:ident) => {
        let $x = 1;
        "hello world"; // ⟵ added semicolon
    }
}

Ignored Semicolon

One (or at least I) would expect the macro m1 below to produce just a statement (judging from the semicolon), i.e. be illegal in expression context. However it somehow does pass as an expression, totally ignoring the semicolon. In the return position of a function it does produce () though [when called like m1!{} – on the other hand m1!() would still produce the integer].

macro_rules! m1 {
    () => {
        1;
    }
}
macro_rules! m2 {
    () => {
        1
    }
}

fn main() {
    let x1 = m1!{};
    println!("{}", x1);
    let x2 = m1!{};
    println!("{}", x2);

    m1!();
    m1!{}
    
    m2!();
//  m2!{}     // illegal
    m2!{};
    
    m1!{}     // apparently even returns ()
}

(Playground)

Output:

1
1

Errors:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.40s
     Running `target/debug/playground`

@petrochenkov
Copy link
Contributor

This issue is very similar to #61733.

@steffahn
Copy link
Member Author

@rustbot modify labels to A-macros, A-frontend, and A-parser.

@rustbot rustbot added A-frontend Area: Compiler frontend (errors, parsing and HIR) A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-parser Area: The parsing of Rust source code to an AST labels Mar 27, 2020
@steffahn
Copy link
Member Author

@rustbot modify labels to +T-lang and +C-bug.

@rustbot rustbot added C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Mar 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: Compiler frontend (errors, parsing and HIR) A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-parser Area: The parsing of Rust source code to an AST C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants