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