Skip to content

for loop desugaring treats the loop's trailing expression in unusual way #61902

Open
@petrochenkov

Description

@petrochenkov

Namely, it's treated as a semicolon-less statement in a middle of the block.

// Like this:
fn main() {
    { 0 } // <- semicolon-less statement in a middle of the block

    ()
}

This is unusual because

  • No other block construction or loop does this.
  • The desugared form cannot be written in source code (it will either need a semicolon, or will be considered trailing).

Git blame says that the behavior was introduced by @Zoxc in #42265.

We cannot remove this behavior because it appears to be useful and code will break if it's removed.
We can, however, use it in other block constructions for which the block's trailing expression does not represent its result.

Block construction Trailing expression is the result
if cond { ... } [else { ... }] Yes
if let pat = expr { ... } [else { ... }] Yes
while cond { ... } No
while let pat = expr { ... } No
for pat in expr { ... } No
loop { ... } No
[unsafe] { ... } Yes
async { ... } ???
try { ... } Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions