Open
Description
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
()
}
- "Semicolon-less" means that its type should unify with
()
(Do not discern between statements with and without semicolon after lowering to HIR #61753). - "In a middle of the block" means that it's not treated as trailing and its lifetime is not extended from the block outwards. That means "does not live long enough" errors like these do not happen (a minimized test case would be appreciated).
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 |