Skip to content

Commit

Permalink
Add a section dedicated to Edition 2024 changes to temporary scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Aug 28, 2024
1 parent 0668397 commit 2b54faf
Showing 1 changed file with 93 additions and 0 deletions.
93 changes: 93 additions & 0 deletions src/destructors.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ smallest scope that contains the expression and is one of the following:
guard.
* The body expression for a match arm.
* The second operand of a [lazy boolean expression].
* *Starting from Edition 2024* the pattern-matching condition and consequent body of [`if let`].
* *Starting from Edition 2024* the entirety of the tail expression of a block.

> **Notes**:
>
Expand Down Expand Up @@ -260,6 +262,97 @@ match PrintOnDrop("Matched value in final expression") {
}
```

#### Changes to temporary scopes by Edition 2024

Edition 2024 introduces two changes to the language regarding temporary scopes.
First, temporary values generated from evaluating the pattern-matching condition
of `if let` will be dropped earlier in general.

```rust,edition2024
struct Droppy(u8);
impl Droppy {
fn get(&self) -> Option<&u8> {
Some(&self.0)
}
}
impl Drop for Droppy {
fn drop(&mut self) {
println!("drop({})", self.0);
}
}
fn call(x: &u8, y: u8, z: &u8) {
println!("call with {x} {y} {z}");
}
let x1 = 0;
let x2 = 3;
call(
if let Some(x) = Droppy(0).get() {
println!("if let consequence");
&x1
} else {
&x2
},
{
let y = Droppy(1);
*y.get().unwrap()
},
Droppy(2).get().unwrap()
);
println!("call ended");
```

This program will print the following.

```text
if let consequence
drop(0)
drop(1)
call with 0 1 2
drop(2)
call ended
```

In other words, `Droppy(0)` is dropped before `Droppy(1)` because its temporary scope is
limited by Edition 2024 to the proper end of the `if let` expression.

Second, temporary values generated from evaluating the tail expression of a block
or a function body will be dropped earlier than the local variable bindings.
The following example demonstrates the Edition 2024 order of events that values
and local variables are dropped.

```rust,edition2024
struct Droppy(u8);
impl Droppy {
fn get(&self) -> Option<&u8> {
Some(&self.0)
}
}
impl Drop for Droppy {
fn drop(&mut self) {
println!("drop({})", self.0);
}
}
fn call() -> u8 {
let x = Droppy(0);
*x.get() + *Droppy(1).get()
}
call();
```

The print-out from this program will be the following.

```text
drop(1)
drop(0)
```

In other words, `Droppy(1)` is dropped earlier than `x`.

### Operands

r[destructors.scope.operands]
Expand Down

0 comments on commit 2b54faf

Please sign in to comment.