Add comments with examples and tests

This commit is contained in:
Roxane
2021-02-25 18:03:41 -05:00
parent fb3b77a8c8
commit 22eaffe71a
32 changed files with 788 additions and 136 deletions

View File

@@ -165,13 +165,42 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields))
}
ExprKind::Closure {
closure_id,
substs,
upvars,
movability,
fake_reads: opt_fake_reads,
} => {
ExprKind::Closure { closure_id, substs, upvars, movability, fake_reads } => {
// Convert the closure fake reads, if any, from `ExprRef` to mir `Place`
// and push the fake reads.
// This must come before creating the operands. This is required in case
// there is a fake read and a borrow of the same path, since otherwise the
// fake read might interfere with the borrow. Consider an example like this
// one:
// ```
// let mut x = 0;
// let c = || {
// &mut x; // mutable borrow of `x`
// match x { _ => () } // fake read of `x`
// };
// ```
// FIXME(RFC2229): Remove feature gate once diagnostics are improved
if this.tcx.features().capture_disjoint_fields {
for (thir_place, cause, hir_id) in fake_reads.into_iter() {
let place_builder =
unpack!(block = this.as_place_builder(block, thir_place));
if let Ok(place_builder_resolved) =
place_builder.try_upvars_resolved(this.tcx, this.typeck_results)
{
let mir_place =
place_builder_resolved.into_place(this.tcx, this.typeck_results);
this.cfg.push_fake_read(
block,
this.source_info(this.tcx.hir().span(hir_id)),
cause,
mir_place,
);
}
}
}
// see (*) above
let operands: Vec<_> = upvars
.into_iter()
@@ -210,21 +239,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
})
.collect();
if let Some(fake_reads) = opt_fake_reads {
for (thir_place, cause) in fake_reads.into_iter() {
let place_builder =
unpack!(block = this.as_place_builder(block, thir_place));
if let Ok(place_builder_resolved) =
place_builder.clone().try_upvars_resolved(this.tcx, this.typeck_results)
{
let mir_place = place_builder_resolved
.clone()
.into_place(this.tcx, this.typeck_results);
this.cfg.push_fake_read(block, source_info, cause, mir_place);
}
}
}
let result = match substs {
UpvarSubsts::Generator(substs) => {