Skip to content

Commit a0ae157

Browse files
committed
Add a couple examples where the spec didn't change
1 parent 71178bb commit a0ae157

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

src/destructors.md

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,24 @@ println!("{}", x);
388388
r[destructors.scope.lifetime-extension.sub-expressions]
389389
If a [borrow], [dereference][dereference expression], [field][field expression], or [tuple indexing expression] has an extended temporary scope, then so does its operand. If an [indexing expression] has an extended temporary scope, then the indexed expression also has an extended temporary scope.
390390

391+
```rust
392+
# use core::sync::atomic::{AtomicU64, Ordering::Relaxed};
393+
# static X: AtomicU64 = AtomicU64::new(0);
394+
# struct PrintOnDrop(&'static str);
395+
# impl Drop for PrintOnDrop {
396+
# fn drop(&mut self) {
397+
# X.fetch_add(1, Relaxed);
398+
# println!("{}", self.0);
399+
# }
400+
# }
401+
let x = &(0, PrintOnDrop("tuple 1 dropped")).0;
402+
let ref y = (0, PrintOnDrop("tuple 2 dropped")).0;
403+
// Though only its first field is borrowed, the temporary for the entire tuple
404+
// lives to the end of the block in both cases.
405+
println!("{x}, {y}");
406+
# assert_eq!(0, X.load(Relaxed));
407+
```
408+
391409
r[destructors.scope.lifetime-extension.patterns]
392410
#### Extending based on patterns
393411

@@ -516,11 +534,18 @@ r[destructors.scope.lifetime-extension.exprs.static]
516534
The extended scope of the body expression of a [static][static item] or [constant item], and of the final expression of a [const block expression], is the entire program. This prevents destructors from being run.
517535
518536
```rust
519-
const C: &Vec<i32> = &Vec::new();
520-
// Usually this would be a dangling reference as the `Vec` would only
521-
// exist inside the initializer expression of `C`, but instead the
522-
// borrow gets lifetime-extended so it effectively has `'static` lifetime.
537+
# #[derive(Debug)] struct PanicOnDrop;
538+
# impl Drop for PanicOnDrop { fn drop(&mut self) { panic!() } }
539+
# impl PanicOnDrop { const fn new() -> PanicOnDrop { PanicOnDrop } }
540+
const C: &PanicOnDrop = &PanicOnDrop::new();
541+
// Usually this would be a dangling reference as the result of
542+
// `PanicOnDrop::new()` would only exist inside the initializer expression of
543+
// `C`, but instead the borrow gets lifetime-extended so it effectively has
544+
// a `'static` lifetime and its destructor is never run.
523545
println!("{:?}", C);
546+
// `const` blocks may likewise extend temporaries to the end of the program:
547+
// the result of `PanicOnDrop::new()` is not dropped.
548+
println!("{:?}", const { &PanicOnDrop::new() });
524549
```
525550
526551
r[destructors.scope.lifetime-extension.exprs.other]

0 commit comments

Comments
 (0)