diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index c46f561e7b32..0359eb9b95d1 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -125,9 +125,18 @@ impl<'tcx> Place<'tcx> { /// be `self` in the current MIR, because that is the only time we directly access the fields /// of a closure type. pub fn is_upvar_field_projection<'cx, 'gcx>(&self, mir: &'cx Mir<'tcx>, - tcx: &TyCtxt<'cx, 'gcx, 'tcx>, - recurse: bool) -> Option { - match *self { + tcx: &TyCtxt<'cx, 'gcx, 'tcx>) -> Option { + let place = if let Place::Projection(ref proj) = self { + if let ProjectionElem::Deref = proj.elem { + &proj.base + } else { + self + } + } else { + self + }; + + match place { Place::Projection(ref proj) => match proj.elem { ProjectionElem::Field(field, _ty) => { let base_ty = proj.base.ty(mir, *tcx).to_ty(*tcx); @@ -138,13 +147,6 @@ impl<'tcx> Place<'tcx> { None } }, - ProjectionElem::Deref => { - if recurse { - proj.base.is_upvar_field_projection(mir, tcx, recurse) - } else { - None - } - }, _ => None, }, _ => None, diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 9f5f1389c66a..5dca01f8842a 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -726,8 +726,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Place::Projection(ref proj) => { match proj.elem { ProjectionElem::Deref => { - let upvar_field_projection = proj.base.is_upvar_field_projection( - self.mir, &self.tcx, false); + let upvar_field_projection = place.is_upvar_field_projection( + self.mir, &self.tcx); if let Some(field) = upvar_field_projection { let var_index = field.index(); let name = self.mir.upvar_decls[var_index].debug_name.to_string(); @@ -788,7 +788,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { autoderef = true; let upvar_field_projection = place.is_upvar_field_projection( - self.mir, &self.tcx, false); + self.mir, &self.tcx); if let Some(field) = upvar_field_projection { let var_index = field.index(); let name = self.mir.upvar_decls[var_index].debug_name.to_string(); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index f37052470c8f..62bf2b0abe4c 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1215,7 +1215,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Operand::Move(ref place @ Place::Projection(_)) | Operand::Copy(ref place @ Place::Projection(_)) => { if let Some(field) = place.is_upvar_field_projection( - self.mir, &self.tcx, false) { + self.mir, &self.tcx) { self.used_mut_upvars.push(field); } } @@ -1804,7 +1804,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { place: place @ Place::Projection(_), is_local_mutation_allowed: _, } => { - if let Some(field) = place.is_upvar_field_projection(self.mir, &self.tcx, false) { + if let Some(field) = place.is_upvar_field_projection(self.mir, &self.tcx) { self.used_mut_upvars.push(field); } } @@ -1867,8 +1867,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // Mutably borrowed data is mutable, but only if we have a // unique path to the `&mut` hir::MutMutable => { - let mode = match proj.base.is_upvar_field_projection( - self.mir, &self.tcx, false) + let mode = match place.is_upvar_field_projection( + self.mir, &self.tcx) { Some(field) if { @@ -1914,7 +1914,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { | ProjectionElem::Subslice { .. } | ProjectionElem::Downcast(..) => { let upvar_field_projection = place.is_upvar_field_projection( - self.mir, &self.tcx, false); + self.mir, &self.tcx); if let Some(field) = upvar_field_projection { let decl = &self.mir.upvar_decls[field.index()]; debug!( diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 93e8f3f86573..c7e28ceb1404 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -175,7 +175,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }; if initial_category == ConstraintCategory::Assignment - && place.is_upvar_field_projection(mir, &infcx.tcx, true).is_some() { + && place.is_upvar_field_projection(mir, &infcx.tcx).is_some() { ConstraintCategory::AssignmentToUpvar } else { initial_category