You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/3637-guard-patterns.md
+12-10Lines changed: 12 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -252,17 +252,10 @@ This can also be seen as a special case of the previous argument, as pattern mac
252
252
253
253
## Deref and Const Patterns Must Be Pure, But Not Guards
254
254
255
-
It may seem odd that we explicitly require `deref!`and const patterns to use pure `Deref`and `PartialEq`implementations, respectively, but allow arbitrary side effects in guards. The ultimate reason for this is that, unlike `deref!`and const patterns, guard patterns are always refutable.
255
+
It may seem odd that we explicitly require const patterns to use pure `PartialEq` implementations (and the upcoming [proposal](https://hackmd.io/4qDDMcvyQ-GDB089IPcHGg) for deref patterns to use pure `Deref` implementations), but allow arbitrary side effects in guards. The ultimate reason for this is that, unlike const patterns and the proposed deref patterns, guard patterns are always refutable.
256
256
257
-
With `deref!` patterns, we can write an impure `Deref` impl which alternates between returning `true` or `false` to get UB:
258
-
```rust
259
-
matchEvilBox::new(false) {
260
-
deref!(true) => {} // Here the `EvilBox` dereferences to `false`.
261
-
deref!(false) => {} // And here to `true`.
262
-
}
263
-
```
264
257
265
-
And similarly, without the requirement of `StructuralPartialEq` we could write a `PartialEq` implementation which always returns `false`:
258
+
Without the requirement of `StructuralPartialEq` we could write a `PartialEq` implementation which always returns `false`, resulting either in UB or a failure to ensure match exhaustiveness:
266
259
267
260
```rust
268
261
constFALSE:EvilBool=EvilBool(false);
@@ -274,7 +267,16 @@ match EvilBool(false) {
274
267
}
275
268
```
276
269
277
-
However, this is not a problem with guard patterns because they already need a irrefutable alternative anyway.
270
+
And similarly, with an impure version of the proposed deref patterns, we could write a `Deref` impl which alternates between returning `true` or `false` to get UB:
271
+
272
+
```rust
273
+
matchEvilBox::new(false) {
274
+
deref!(true) => {} // Here the `EvilBox` dereferences to `false`.
275
+
deref!(false) => {} // And here to `true`.
276
+
}
277
+
```
278
+
279
+
However, this is not a problem with guard patterns because they already need an irrefutable alternative anyway.
278
280
For example, we could rewrite the const pattern example with guard patterns as follows:
0 commit comments