rust-lang / rust-lang/rust

macro forwarded `stmt` fragments causes type error for expression statements in the body of a block

Open
#149,260 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-decl-macros-1-2 A-macros A-parser C-bug T-compiler T-lang
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

when a stmt metavariable captures an expression statement of non-unit type, and it is expanded at non-tail position in a block, rustc will issue a type mismatch error.

I tried this code (same code on playground):

macro_rules! x {
    ($($s:stmt);*) => {
        $($s)*
        // adding semicolons like the next two lines does NOT work
        // $($s);*
        // $($s;)*
    }
}

fn main() {
    x! {
        42;
        ()
    }
}

I expected to see this happen: the code compiles

Instead, this happened: "E0308: expected (), found Integer".

the above snippet uses a integer literal, but in the real code, the expression statement that caused the error is a function call with a non-unit return type.

note, because the metavariable is captured as a stmt fragment, not expr, adding a semicolon in the expanded code does not work. it actually triggers a unnecessary trailing semicolon warning.

enclosing the entire expansion in its own block (e.g. (...) => {{ ... }}) does not work either.

this problem was first posted to the user forum:

https://users.rust-lang.org/t/macro-miscompilation-type-error-when-expanding-macro/136450

in the post, the macro in question was designed to insert cancellation check points between individual statement of a concurrent task.

I searched the issue tracker using keywords like macro, macro_rules, statement, stmt, type, and can't find an existing report.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the minimized macro_rules example with rustc or the linked Rust Playground, focusing on how forwarded stmt fragments are expanded in a block. The issue is resolved when the example compiles without the E0308 mismatch or an unnecessary trailing-semicolon warning, with regression coverage for the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.