Skip to content

Commit b50aeb1

Browse files
authored
Merge pull request #1953 from dianne/pattern-drop-order
specify relative drop order of pattern bindings
2 parents 1be151c + f153d01 commit b50aeb1

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

src/destructors.md

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,59 @@ let declared_first = PrintOnDrop("Dropped last in outer scope");
185185
let declared_last = PrintOnDrop("Dropped first in outer scope");
186186
```
187187

188-
r[destructors.scope.bindings.match-pattern-order]
189-
If multiple patterns are used in the same arm for a `match` expression, then an
190-
unspecified pattern will be used to determine the drop order.
188+
r[destructors.scope.bindings.patterns]
189+
Variables in patterns are dropped in reverse order of declaration within the pattern.
190+
191+
```rust
192+
# struct PrintOnDrop(&'static str);
193+
# impl Drop for PrintOnDrop {
194+
# fn drop(&mut self) {
195+
# println!("drop({})", self.0);
196+
# }
197+
# }
198+
let (declared_first, declared_last) = (
199+
PrintOnDrop("Dropped last"),
200+
PrintOnDrop("Dropped first"),
201+
);
202+
```
203+
204+
r[destructors.scope.bindings.or-patterns]
205+
For the purpose of drop order, [or-patterns] declare bindings in the order given by the first subpattern.
206+
207+
```rust
208+
# struct PrintOnDrop(&'static str);
209+
# impl Drop for PrintOnDrop {
210+
# fn drop(&mut self) {
211+
# println!("drop({})", self.0);
212+
# }
213+
# }
214+
// Drops `x` before `y`.
215+
fn or_pattern_drop_order<T>(
216+
(Ok([x, y]) | Err([y, x])): Result<[T; 2], [T; 2]>
217+
// ^^^^^^^^^^ ^^^^^^^^^^^ This is the second subpattern.
218+
// |
219+
// This is the first subpattern.
220+
//
221+
// In the first subpattern, `x` is declared before `y`. Since it is
222+
// the first subpattern, that is the order used even if the second
223+
// subpattern, where the bindings are declared in the opposite
224+
// order, is matched.
225+
) {}
226+
227+
// Here we match the first subpattern, and the drops happen according
228+
// to the declaration order in the first subpattern.
229+
or_pattern_drop_order(Ok([
230+
PrintOnDrop("Declared first, dropped last"),
231+
PrintOnDrop("Declared last, dropped first"),
232+
]));
233+
234+
// Here we match the second subpattern, and the drops still happen
235+
// according to the declaration order in the first subpattern.
236+
or_pattern_drop_order(Err([
237+
PrintOnDrop("Declared last, dropped first"),
238+
PrintOnDrop("Declared first, dropped last"),
239+
]));
240+
```
191241

192242
r[destructors.scope.temporary]
193243
### Temporary scopes
@@ -473,6 +523,7 @@ There is one additional case to be aware of: when a panic reaches a [non-unwindi
473523
[Trait objects]: types/trait-object.md
474524
[tuple]: types/tuple.md
475525

526+
[or-patterns]: patterns.md#or-patterns
476527
[slice pattern]: patterns.md#slice-patterns
477528
[struct pattern]: patterns.md#struct-patterns
478529
[tuple pattern]: patterns.md#tuple-patterns

0 commit comments

Comments
 (0)