Skip to content

Commit 2b54faf

Browse files
Add a section dedicated to Edition 2024 changes to temporary scopes
1 parent 0668397 commit 2b54faf

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

src/destructors.md

+93
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ smallest scope that contains the expression and is one of the following:
211211
guard.
212212
* The body expression for a match arm.
213213
* The second operand of a [lazy boolean expression].
214+
* *Starting from Edition 2024* the pattern-matching condition and consequent body of [`if let`].
215+
* *Starting from Edition 2024* the entirety of the tail expression of a block.
214216

215217
> **Notes**:
216218
>
@@ -260,6 +262,97 @@ match PrintOnDrop("Matched value in final expression") {
260262
}
261263
```
262264

265+
#### Changes to temporary scopes by Edition 2024
266+
267+
Edition 2024 introduces two changes to the language regarding temporary scopes.
268+
First, temporary values generated from evaluating the pattern-matching condition
269+
of `if let` will be dropped earlier in general.
270+
271+
```rust,edition2024
272+
struct Droppy(u8);
273+
impl Droppy {
274+
fn get(&self) -> Option<&u8> {
275+
Some(&self.0)
276+
}
277+
}
278+
impl Drop for Droppy {
279+
fn drop(&mut self) {
280+
println!("drop({})", self.0);
281+
}
282+
}
283+
284+
fn call(x: &u8, y: u8, z: &u8) {
285+
println!("call with {x} {y} {z}");
286+
}
287+
288+
let x1 = 0;
289+
let x2 = 3;
290+
291+
call(
292+
if let Some(x) = Droppy(0).get() {
293+
println!("if let consequence");
294+
&x1
295+
} else {
296+
&x2
297+
},
298+
{
299+
let y = Droppy(1);
300+
*y.get().unwrap()
301+
},
302+
Droppy(2).get().unwrap()
303+
);
304+
println!("call ended");
305+
```
306+
307+
This program will print the following.
308+
309+
```text
310+
if let consequence
311+
drop(0)
312+
drop(1)
313+
call with 0 1 2
314+
drop(2)
315+
call ended
316+
```
317+
318+
In other words, `Droppy(0)` is dropped before `Droppy(1)` because its temporary scope is
319+
limited by Edition 2024 to the proper end of the `if let` expression.
320+
321+
Second, temporary values generated from evaluating the tail expression of a block
322+
or a function body will be dropped earlier than the local variable bindings.
323+
The following example demonstrates the Edition 2024 order of events that values
324+
and local variables are dropped.
325+
326+
```rust,edition2024
327+
struct Droppy(u8);
328+
impl Droppy {
329+
fn get(&self) -> Option<&u8> {
330+
Some(&self.0)
331+
}
332+
}
333+
impl Drop for Droppy {
334+
fn drop(&mut self) {
335+
println!("drop({})", self.0);
336+
}
337+
}
338+
339+
fn call() -> u8 {
340+
let x = Droppy(0);
341+
*x.get() + *Droppy(1).get()
342+
}
343+
344+
call();
345+
```
346+
347+
The print-out from this program will be the following.
348+
349+
```text
350+
drop(1)
351+
drop(0)
352+
```
353+
354+
In other words, `Droppy(1)` is dropped earlier than `x`.
355+
263356
### Operands
264357

265358
r[destructors.scope.operands]

0 commit comments

Comments
 (0)