@@ -214,9 +214,51 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
214
214
///
215
215
/// ## False edges
216
216
///
217
- /// We don't want to have the exact structure of the decision tree be
218
- /// visible through borrow checking. False edges ensure that the CFG as
219
- /// seen by borrow checking doesn't encode this. False edges are added:
217
+ /// We don't want to have the exact structure of the decision tree be visible through borrow
218
+ /// checking. Specifically we want borrowck to think that:
219
+ /// - at any point, any or none of the patterns and guards seen so far may have been tested;
220
+ /// - after the match, any of the patterns may have matched.
221
+ ///
222
+ /// For example, all of these would fail to error if borrowck could see the real CFG (examples
223
+ /// taken from `tests/ui/nll/match-cfg-fake-edges.rs`):
224
+ /// ```ignore (too many errors, this is already in the test suite)
225
+ /// let x = String::new();
226
+ /// let _ = match true {
227
+ /// _ => {},
228
+ /// _ => drop(x),
229
+ /// };
230
+ /// // Borrowck must not know the second arm is never run.
231
+ /// drop(x); //~ ERROR use of moved value
232
+ ///
233
+ /// let x;
234
+ /// # let y = true;
235
+ /// match y {
236
+ /// _ if { x = 2; true } => {},
237
+ /// // Borrowck must not know the guard is always run.
238
+ /// _ => drop(x), //~ ERROR used binding `x` is possibly-uninitialized
239
+ /// };
240
+ ///
241
+ /// let x = String::new();
242
+ /// # let y = true;
243
+ /// match y {
244
+ /// false if { drop(x); true } => {},
245
+ /// // Borrowck must not know the guard is not run in the `true` case.
246
+ /// true => drop(x), //~ ERROR use of moved value: `x`
247
+ /// false => {},
248
+ /// };
249
+ ///
250
+ /// # let mut y = (true, true);
251
+ /// let r = &mut y.1;
252
+ /// match y {
253
+ /// //~^ ERROR cannot use `y.1` because it was mutably borrowed
254
+ /// (false, true) => {}
255
+ /// // Borrowck must not know we don't test `y.1` when `y.0` is `true`.
256
+ /// (true, _) => drop(r),
257
+ /// (false, _) => {}
258
+ /// };
259
+ /// ```
260
+ ///
261
+ /// To ensure this, we add false edges:
220
262
///
221
263
/// * From each pre-binding block to the next pre-binding block.
222
264
/// * From each otherwise block to the next pre-binding block.
0 commit comments