Why do blocks take ownership

⚓ Rust    📅 2025-06-20    👤 surdeus    👁️ 6      

surdeus

Warning

This post was published 54 days ago. The information described in this article may have changed.

Taking a look at block expressions I find that a block can take ownership of a variable:

fn move_by_block_expression() {
    let s = String::from("hell");

    // Move the value out of `s` in the block expression.
    { s }; // ofc, we can assign this to other variable.
    s; //fails, s was moved
}

fn main() {
    move_by_block_expression();
}

The move is unexpected for me. I tried some conceptualisation that I briefly describe below.

  • Treat the block as an anonymous function taking a parameter?

  • Otherwise I wouldn't expect it to be dropped: should happen when a variable goes out of scope which isn't the case here.

    • To cite the docs:

      When an initialized variable or temporary goes out of scope, its destructor is run, or it is dropped.

      I get though, I'm citing a single passage.

  • Another possibility is that the return of the block has something to do with but (&{ s; }); moves, so that can't be the case.

  • Maybe the block is more like an immediately executable closure, that uses move (a closure like (move || s)())

I did read parts of the articles for scopes and destructors.

They say, for example

Given a function, or closure, there are drop scopes for:

  • Each block, including the function body
  • In the case of a block expression, the scope for the block and the expression are the same scope.

That may answer it but I don't exactly understand it.

Maybe my confusion is simply that drop scopes and the general "scopes" are different? So a variable is drop in a drop scope, even if its own scope is longer-lived (like an outer block) ?

Or I wonder whether there is some other way to conceptualise why blocks take ownership / move ?

15 posts - 4 participants

Read full topic

🏷️ rust_feed