From 24f91e878244990595649120f402cc13263ae54f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 27 Jun 2018 16:13:33 -0300 Subject: [PATCH] Move find_use stuff to it's own file --- .../nll/explain_borrow/find_use.rs | 142 ++++++++++++++++++ .../borrow_check/nll/explain_borrow/mod.rs | 139 +---------------- 2 files changed, 148 insertions(+), 133 deletions(-) create mode 100644 src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs new file mode 100644 index 000000000000..58e9d814826b --- /dev/null +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs @@ -0,0 +1,142 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use borrow_check::borrow_set::BorrowData; +use borrow_check::nll::region_infer::RegionInferenceContext; +use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor}; +use rustc::mir::{Local, Location, Mir}; +use rustc_data_structures::fx::FxHashSet; +use util::liveness::{self, DefUse, LivenessMode}; + +crate fn regular_use<'gcx, 'tcx>( + mir: &'gcx Mir, + regioncx: &'tcx RegionInferenceContext, + borrow: &'tcx BorrowData, + start_point: Location, + local: Local, +) -> Option { + let mut uf = UseFinder { + mir, + regioncx, + borrow, + start_point, + local, + liveness_mode: LivenessMode { + include_regular_use: true, + include_drops: false, + }, + }; + + uf.find() +} + +crate fn drop_use<'gcx, 'tcx>( + mir: &'gcx Mir, + regioncx: &'tcx RegionInferenceContext, + borrow: &'tcx BorrowData, + start_point: Location, + local: Local, +) -> Option { + let mut uf = UseFinder { + mir, + regioncx, + borrow, + start_point, + local, + liveness_mode: LivenessMode { + include_regular_use: false, + include_drops: true, + }, + }; + + uf.find() +} + +struct UseFinder<'gcx, 'tcx> { + mir: &'gcx Mir<'gcx>, + regioncx: &'tcx RegionInferenceContext<'tcx>, + borrow: &'tcx BorrowData<'tcx>, + start_point: Location, + local: Local, + liveness_mode: LivenessMode, +} + +impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> { + fn find(&mut self) -> Option { + let mut stack = vec![]; + let mut visited = FxHashSet(); + + stack.push(self.start_point); + while let Some(p) = stack.pop() { + if !self.regioncx.region_contains_point(self.borrow.region, p) { + continue; + } + + if !visited.insert(p) { + continue; + } + + let block_data = &self.mir[p.block]; + let (defined, used) = self.def_use(p, block_data.visitable(p.statement_index)); + + if used { + return Some(p); + } else if !defined { + if p.statement_index < block_data.statements.len() { + stack.push(Location { + statement_index: p.statement_index + 1, + ..p + }); + } else { + stack.extend(block_data.terminator().successors().map(|&basic_block| { + Location { + statement_index: 0, + block: basic_block, + } + })); + } + } + } + + None + } + + fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) { + let mut visitor = DefUseVisitor { + defined: false, + used: false, + local: self.local, + liveness_mode: self.liveness_mode, + }; + + thing.apply(location, &mut visitor); + + (visitor.defined, visitor.used) + } +} + +struct DefUseVisitor { + defined: bool, + used: bool, + local: Local, + liveness_mode: LivenessMode, +} + +impl<'tcx> Visitor<'tcx> for DefUseVisitor { + fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) { + if local == self.local { + match liveness::categorize(context, self.liveness_mode) { + Some(DefUse::Def) => self.defined = true, + Some(DefUse::Use) => self.used = true, + None => (), + } + } + } +} 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 4f37b338e92b..acc164b14c31 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -9,13 +9,12 @@ // except according to those terms. use borrow_check::borrow_set::BorrowData; -use borrow_check::nll::region_infer::{Cause, RegionInferenceContext}; +use borrow_check::nll::region_infer::Cause; use borrow_check::{Context, MirBorrowckCtxt, WriteKind}; -use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor}; -use rustc::mir::{Local, Location, Mir, Place}; -use rustc_data_structures::fx::FxHashSet; +use rustc::mir::Place; use rustc_errors::DiagnosticBuilder; -use util::liveness::{self, DefUse, LivenessMode}; + +mod find_use; impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// Adds annotations to `err` explaining *why* the borrow contains the @@ -45,7 +44,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let borrow_region_vid = regioncx.to_region_vid(borrow.region); if let Some(cause) = regioncx.why_region_contains_point(borrow_region_vid, context.loc) { match cause { - Cause::LiveVar(local, location) => match find_regular_use( + Cause::LiveVar(local, location) => match find_use::regular_use( mir, regioncx, borrow, location, local, ) { Some(p) => { @@ -60,7 +59,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } }, - Cause::DropVar(local, location) => match find_drop_use( + Cause::DropVar(local, location) => match find_use::drop_use( mir, regioncx, borrow, location, local, ) { Some(p) => match &mir.local_decls[local].name { @@ -124,129 +123,3 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } } - -fn find_regular_use<'gcx, 'tcx>( - mir: &'gcx Mir, - regioncx: &'tcx RegionInferenceContext, - borrow: &'tcx BorrowData, - start_point: Location, - local: Local, -) -> Option { - let mut uf = UseFinder { - mir, - regioncx, - borrow, - start_point, - local, - liveness_mode: LivenessMode { - include_regular_use: true, - include_drops: false, - }, - }; - - uf.find() -} - -fn find_drop_use<'gcx, 'tcx>( - mir: &'gcx Mir, - regioncx: &'tcx RegionInferenceContext, - borrow: &'tcx BorrowData, - start_point: Location, - local: Local, -) -> Option { - let mut uf = UseFinder { - mir, - regioncx, - borrow, - start_point, - local, - liveness_mode: LivenessMode { - include_regular_use: false, - include_drops: true, - }, - }; - - uf.find() -} - -struct UseFinder<'gcx, 'tcx> { - mir: &'gcx Mir<'gcx>, - regioncx: &'tcx RegionInferenceContext<'tcx>, - borrow: &'tcx BorrowData<'tcx>, - start_point: Location, - local: Local, - liveness_mode: LivenessMode, -} - -impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> { - fn find(&mut self) -> Option { - let mut stack = vec![]; - let mut visited = FxHashSet(); - - stack.push(self.start_point); - while let Some(p) = stack.pop() { - if !self.regioncx.region_contains_point(self.borrow.region, p) { - continue; - } - - if !visited.insert(p) { - continue; - } - - let block_data = &self.mir[p.block]; - let (defined, used) = self.def_use(p, block_data.visitable(p.statement_index)); - - if used { - return Some(p); - } else if !defined { - if p.statement_index < block_data.statements.len() { - stack.push(Location { - statement_index: p.statement_index + 1, - ..p - }); - } else { - stack.extend(block_data.terminator().successors().map(|&basic_block| { - Location { - statement_index: 0, - block: basic_block, - } - })); - } - } - } - - None - } - - fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) { - let mut visitor = DefUseVisitor { - defined: false, - used: false, - local: self.local, - liveness_mode: self.liveness_mode, - }; - - thing.apply(location, &mut visitor); - - (visitor.defined, visitor.used) - } -} - -struct DefUseVisitor { - defined: bool, - used: bool, - local: Local, - liveness_mode: LivenessMode, -} - -impl<'tcx> Visitor<'tcx> for DefUseVisitor { - fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) { - if local == self.local { - match liveness::categorize(context, self.liveness_mode) { - Some(DefUse::Def) => self.defined = true, - Some(DefUse::Use) => self.used = true, - None => (), - } - } - } -}