X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_mir%2Fborrow_check%2Fnll%2Fexplain_borrow%2Fmod.rs;h=aba3ef1cbbfc9a64ec41f9e2ee9f0bbdd2f77898;hb=d1d256592bcd3f05d00fe7ad80d1a1ed22c9e7d7;hp=ed88b16253584634bb1db1426144ad06cc4f47a8;hpb=09ab31bc64f4ede9f9498440cb4225c173767c1e;p=rust.git diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index ed88b162535..5354b45f92d 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -7,7 +7,7 @@ use crate::borrow_check::{MirBorrowckCtxt, WriteKind}; use rustc::mir::{ CastKind, ConstraintCategory, FakeReadCause, Local, Location, Body, Operand, Place, PlaceBase, - Projection, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, + Rvalue, Statement, StatementKind, TerminatorKind, }; use rustc::ty::{self, TyCtxt}; use rustc::ty::adjustment::{PointerCast}; @@ -17,6 +17,7 @@ mod find_use; +#[derive(Debug)] pub(in crate::borrow_check) enum BorrowExplanation { UsedLater(LaterUseKind, Span), UsedLaterInLoop(LaterUseKind, Span), @@ -35,7 +36,7 @@ pub(in crate::borrow_check) enum BorrowExplanation { Unexplained, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub(in crate::borrow_check) enum LaterUseKind { TraitCapture, ClosureCapture, @@ -95,7 +96,7 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>( should_note_order, } => { let local_decl = &body.local_decls[dropped_local]; - let (dtor_desc, type_desc) = match local_decl.ty.sty { + let (dtor_desc, type_desc) = match local_decl.ty.kind { // If type is an ADT that implements Drop, then // simplify output by reporting just the ADT name. ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => ( @@ -252,7 +253,7 @@ pub(in crate::borrow_check) fn explain_why_borrow_contains_point( Some(Cause::LiveVar(local, location)) => { let span = body.source_info(location).span; let spans = self - .move_spans(&Place::from(local), location) + .move_spans(Place::from(local).as_ref(), location) .or_else(|| self.borrow_spans(span, location)); let borrow_location = location; @@ -272,7 +273,10 @@ pub(in crate::borrow_check) fn explain_why_borrow_contains_point( let mut should_note_order = false; if body.local_decls[local].name.is_some() { if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place { - if let Place::Base(PlaceBase::Local(borrowed_local)) = place { + if let Place { + base: PlaceBase::Local(borrowed_local), + projection: box [], + } = place { if body.local_decls[*borrowed_local].name.is_some() && local != *borrowed_local { @@ -301,7 +305,8 @@ pub(in crate::borrow_check) fn explain_why_borrow_contains_point( region, ); if let Some(region_name) = region_name { - let opt_place_desc = self.describe_place(&borrow.borrowed_place); + let opt_place_desc = + self.describe_place(borrow.borrowed_place.as_ref()); BorrowExplanation::MustBeValidFor { category, from_closure, @@ -489,8 +494,14 @@ fn later_use_kind( // Just point to the function, to reduce the chance of overlapping spans. let function_span = match func { Operand::Constant(c) => c.span, - Operand::Copy(Place::Base(PlaceBase::Local(l))) | - Operand::Move(Place::Base(PlaceBase::Local(l))) => { + Operand::Copy(Place { + base: PlaceBase::Local(l), + projection: box [], + }) | + Operand::Move(Place { + base: PlaceBase::Local(l), + projection: box [], + }) => { let local_decl = &self.body.local_decls[*l]; if local_decl.name.is_none() { local_decl.source_info.span @@ -531,7 +542,10 @@ fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool { // it which simplifies the termination logic. let mut queue = vec![location]; let mut target = if let Some(&Statement { - kind: StatementKind::Assign(Place::Base(PlaceBase::Local(local)), _), + kind: StatementKind::Assign(box(Place { + base: PlaceBase::Local(local), + projection: box [], + }, _)), .. }) = stmt { @@ -554,14 +568,10 @@ fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool { debug!("was_captured_by_trait_object: stmt={:?}", stmt); // The only kind of statement that we care about is assignments... - if let StatementKind::Assign(place, box rvalue) = &stmt.kind { - let into = match place { - Place::Base(PlaceBase::Local(into)) => into, - Place::Projection(box Projection { - base: Place::Base(PlaceBase::Local(into)), - elem: ProjectionElem::Deref, - }) => into, - _ => { + if let StatementKind::Assign(box(place, rvalue)) = &stmt.kind { + let into = match place.local_or_deref_local() { + Some(into) => into, + None => { // Continue at the next location. queue.push(current_location.successor_within_block()); continue; @@ -572,11 +582,17 @@ fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool { // If we see a use, we should check whether it is our data, and if so // update the place that we're looking for to that new place. Rvalue::Use(operand) => match operand { - Operand::Copy(Place::Base(PlaceBase::Local(from))) - | Operand::Move(Place::Base(PlaceBase::Local(from))) + Operand::Copy(Place { + base: PlaceBase::Local(from), + projection: box [], + }) + | Operand::Move(Place { + base: PlaceBase::Local(from), + projection: box [], + }) if *from == target => { - target = *into; + target = into; } _ => {} }, @@ -585,13 +601,19 @@ fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool { Rvalue::Cast( CastKind::Pointer(PointerCast::Unsize), operand, ty ) => match operand { - Operand::Copy(Place::Base(PlaceBase::Local(from))) - | Operand::Move(Place::Base(PlaceBase::Local(from))) + Operand::Copy(Place { + base: PlaceBase::Local(from), + projection: box [], + }) + | Operand::Move(Place { + base: PlaceBase::Local(from), + projection: box [], + }) if *from == target => { debug!("was_captured_by_trait_object: ty={:?}", ty); // Check the type for a trait object. - return match ty.sty { + return match ty.kind { // `&dyn Trait` ty::Ref(_, ty, _) if ty.is_trait() => true, // `Box` @@ -616,7 +638,10 @@ fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool { debug!("was_captured_by_trait_object: terminator={:?}", terminator); if let TerminatorKind::Call { - destination: Some((Place::Base(PlaceBase::Local(dest)), block)), + destination: Some((Place { + base: PlaceBase::Local(dest), + projection: box [], + }, block)), args, .. } = &terminator.kind @@ -627,7 +652,10 @@ fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool { ); // Check if one of the arguments to this function is the target place. let found_target = args.iter().any(|arg| { - if let Operand::Move(Place::Base(PlaceBase::Local(potential))) = arg { + if let Operand::Move(Place { + base: PlaceBase::Local(potential), + projection: box [], + }) = arg { *potential == target } else { false