Rollup merge of #83521 - sexxi-goose:quick-diagnostic-fix, r=nikomatsakis
2229: Fix diagnostic issue when using FakeReads in closures This PR fixes a diagnostic issue caused by https://github.com/rust-lang/rust/pull/82536. A temporary work around was used in this merged PR which involved feature gating the addition of FakeReads introduced as a result of pattern matching in closures. The fix involves adding an optional closure DefId to ForLet and ForMatchedPlace FakeReadCauses. This DefId will only be added if a closure pattern matches a Place starting with an Upvar. r? ```@nikomatsakis```
This commit is contained in:
commit
a89eab9bca
39 changed files with 132 additions and 91 deletions
|
@ -1728,7 +1728,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'tcx> {
|
||||
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
|
||||
match statement {
|
||||
Statement { kind: StatementKind::FakeRead(cause, box place), .. }
|
||||
Statement { kind: StatementKind::FakeRead(box (cause, place)), .. }
|
||||
if *place == self.place =>
|
||||
{
|
||||
self.cause = Some(*cause);
|
||||
|
|
|
@ -515,7 +515,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let block = &self.body.basic_blocks()[location.block];
|
||||
|
||||
let kind = if let Some(&Statement {
|
||||
kind: StatementKind::FakeRead(FakeReadCause::ForLet, _),
|
||||
kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), _)),
|
||||
..
|
||||
}) = block.statements.get(location.statement_index)
|
||||
{
|
||||
|
|
|
@ -7,8 +7,8 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::lang_items::LangItemGroup;
|
||||
use rustc_hir::GeneratorKind;
|
||||
use rustc_middle::mir::{
|
||||
AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place,
|
||||
PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
|
||||
AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand,
|
||||
Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
|
||||
};
|
||||
use rustc_middle::ty::print::Print;
|
||||
use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt};
|
||||
|
@ -795,6 +795,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// StatementKind::FakeRead only contains a def_id if they are introduced as a result
|
||||
// of pattern matching within a closure.
|
||||
if let StatementKind::FakeRead(box (cause, ref place)) = stmt.kind {
|
||||
match cause {
|
||||
FakeReadCause::ForMatchedPlace(Some(closure_def_id))
|
||||
| FakeReadCause::ForLet(Some(closure_def_id)) => {
|
||||
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
|
||||
let places = &[Operand::Move(*place)];
|
||||
if let Some((args_span, generator_kind, var_span)) =
|
||||
self.closure_span(closure_def_id, moved_place, places)
|
||||
{
|
||||
return ClosureUse { generator_kind, args_span, var_span };
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let normal_ret =
|
||||
if moved_place.projection.iter().any(|p| matches!(p, ProjectionElem::Downcast(..))) {
|
||||
PatUse(stmt.source_info.span)
|
||||
|
|
|
@ -63,7 +63,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
|||
|
||||
self.mutate_place(location, *lhs, Shallow(None), JustWrite);
|
||||
}
|
||||
StatementKind::FakeRead(_, _) => {
|
||||
StatementKind::FakeRead(box (_, _)) => {
|
||||
// Only relevant for initialized/liveness/safety checks.
|
||||
}
|
||||
StatementKind::SetDiscriminant { place, variant_index: _ } => {
|
||||
|
|
|
@ -574,7 +574,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
|
|||
|
||||
self.mutate_place(location, (*lhs, span), Shallow(None), JustWrite, flow_state);
|
||||
}
|
||||
StatementKind::FakeRead(_, box ref place) => {
|
||||
StatementKind::FakeRead(box (_, ref place)) => {
|
||||
// Read for match doesn't access any memory and is used to
|
||||
// assert that a place is safe and live. So we don't have to
|
||||
// do any checks here.
|
||||
|
|
|
@ -293,8 +293,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
}
|
||||
self.gather_rvalue(rval);
|
||||
}
|
||||
StatementKind::FakeRead(_, place) => {
|
||||
self.create_move_path(**place);
|
||||
StatementKind::FakeRead(box (_, place)) => {
|
||||
self.create_move_path(*place);
|
||||
}
|
||||
StatementKind::LlvmInlineAsm(ref asm) => {
|
||||
for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) {
|
||||
|
|
|
@ -683,10 +683,10 @@ pub(super) fn filtered_statement_span(
|
|||
// and `_1` is the `Place` for `somenum`.
|
||||
//
|
||||
// If and when the Issue is resolved, remove this special case match pattern:
|
||||
StatementKind::FakeRead(cause, _) if cause == FakeReadCause::ForGuardBinding => None,
|
||||
StatementKind::FakeRead(box (cause, _)) if cause == FakeReadCause::ForGuardBinding => None,
|
||||
|
||||
// Retain spans from all other statements
|
||||
StatementKind::FakeRead(_, _) // Not including `ForGuardBinding`
|
||||
StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding`
|
||||
| StatementKind::CopyNonOverlapping(..)
|
||||
| StatementKind::Assign(_)
|
||||
| StatementKind::SetDiscriminant { .. }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue