From b2d16f3b966766cd654c756bcec5f8f8d0a39c20 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 26 Jun 2018 14:24:54 -0300 Subject: [PATCH 1/4] let add_element return by itself --- src/librustc_mir/borrow_check/nll/region_infer/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 09e425ff555..014b37a0a27 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -343,11 +343,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("add_live_point: @{:?} Adding cause {:?}", point, cause); let element = self.elements.index(point); - if self.liveness_constraints.add_element(v, element, &cause) { - true - } else { - false - } + self.liveness_constraints.add_element(v, element, &cause) } /// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`. From 24f91e878244990595649120f402cc13263ae54f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 27 Jun 2018 16:13:33 -0300 Subject: [PATCH 2/4] 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 00000000000..58e9d814826 --- /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 4f37b338e92..acc164b14c3 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 => (), - } - } - } -} From 0957ede5027c0bffe208904998675a17bfd4cd59 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 1 Jul 2018 19:43:01 -0300 Subject: [PATCH 3/4] Make causal tracking lazy --- src/librustc/mir/mod.rs | 29 +++ .../borrow_check/nll/constraint_generation.rs | 26 +-- .../nll/explain_borrow/find_use.rs | 172 ++++++++++-------- .../borrow_check/nll/explain_borrow/mod.rs | 123 ++++++------- .../nll/region_infer/error_reporting.rs | 15 +- .../borrow_check/nll/region_infer/mod.rs | 18 +- .../borrow_check/nll/region_infer/values.rs | 84 +-------- .../borrow_check/nll/type_check/liveness.rs | 10 +- .../borrow_check/nll/type_check/mod.rs | 4 +- src/test/ui/generator/borrowing.nll.stderr | 9 +- .../ref-escapes-but-not-over-yield.nll.stderr | 18 +- src/test/ui/issue-47646.stderr | 8 +- .../span/destructor-restrictions.nll.stderr | 9 +- ...locals-die-before-temps-of-body.nll.stderr | 19 +- 14 files changed, 225 insertions(+), 319 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index dec37bdf719..dca0d4f442a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1000,6 +1000,10 @@ impl<'tcx> Terminator<'tcx> { self.kind.successors_mut() } + pub fn unwind(&self) -> Option<&Option> { + self.kind.unwind() + } + pub fn unwind_mut(&mut self) -> Option<&mut Option> { self.kind.unwind_mut() } @@ -1195,6 +1199,31 @@ impl<'tcx> TerminatorKind<'tcx> { } } + pub fn unwind(&self) -> Option<&Option> { + match *self { + TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::Abort + | TerminatorKind::Return + | TerminatorKind::Unreachable + | TerminatorKind::GeneratorDrop + | TerminatorKind::Yield { .. } + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::FalseEdges { .. } => None, + TerminatorKind::Call { + cleanup: ref unwind, + .. + } + | TerminatorKind::Assert { + cleanup: ref unwind, + .. + } + | TerminatorKind::DropAndReplace { ref unwind, .. } + | TerminatorKind::Drop { ref unwind, .. } + | TerminatorKind::FalseUnwind { ref unwind, .. } => Some(unwind), + } + } + pub fn unwind_mut(&mut self) -> Option<&mut Option> { match *self { TerminatorKind::Goto { .. } diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 68aa9aeabf8..25a0123755f 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -12,7 +12,7 @@ use borrow_check::borrow_set::BorrowSet; use borrow_check::location::LocationTable; use borrow_check::nll::ToRegionVid; use borrow_check::nll::facts::AllFacts; -use borrow_check::nll::region_infer::{Cause, RegionInferenceContext}; +use borrow_check::nll::region_infer::RegionInferenceContext; use borrow_check::nll::type_check::AtLocation; use rustc::hir; use rustc::infer::InferCtxt; @@ -33,7 +33,7 @@ pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>( location_table: &LocationTable, mir: &Mir<'tcx>, borrow_set: &BorrowSet<'tcx>, - liveness_set_from_typeck: &[(ty::Region<'tcx>, Location, Cause)], + liveness_set_from_typeck: &[(ty::Region<'tcx>, Location)], ) { let mut cg = ConstraintGeneration { borrow_set, @@ -69,14 +69,14 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx /// We sometimes have `substs` within an rvalue, or within a /// call. Make them live at the location where they appear. fn visit_substs(&mut self, substs: &&'tcx Substs<'tcx>, location: Location) { - self.add_regular_live_constraint(*substs, location, Cause::LiveOther(location)); + self.add_regular_live_constraint(*substs, location); self.super_substs(substs); } /// We sometimes have `region` within an rvalue, or within a /// call. Make them live at the location where they appear. fn visit_region(&mut self, region: &ty::Region<'tcx>, location: Location) { - self.add_regular_live_constraint(*region, location, Cause::LiveOther(location)); + self.add_regular_live_constraint(*region, location); self.super_region(region); } @@ -94,7 +94,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx ); } TyContext::Location(location) => { - self.add_regular_live_constraint(*ty, location, Cause::LiveOther(location)); + self.add_regular_live_constraint(*ty, location); } } @@ -104,14 +104,14 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx /// We sometimes have `generator_substs` within an rvalue, or within a /// call. Make them live at the location where they appear. fn visit_generator_substs(&mut self, substs: &GeneratorSubsts<'tcx>, location: Location) { - self.add_regular_live_constraint(*substs, location, Cause::LiveOther(location)); + self.add_regular_live_constraint(*substs, location); self.super_generator_substs(substs); } /// We sometimes have `closure_substs` within an rvalue, or within a /// call. Make them live at the location where they appear. fn visit_closure_substs(&mut self, substs: &ClosureSubsts<'tcx>, location: Location) { - self.add_regular_live_constraint(*substs, location, Cause::LiveOther(location)); + self.add_regular_live_constraint(*substs, location); self.super_closure_substs(substs); } @@ -233,7 +233,7 @@ impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> { /// that we also have to respect. fn add_region_liveness_constraints_from_type_check( &mut self, - liveness_set: &[(ty::Region<'tcx>, Location, Cause)], + liveness_set: &[(ty::Region<'tcx>, Location)], ) { debug!( "add_region_liveness_constraints_from_type_check(liveness_set={} items)", @@ -247,16 +247,16 @@ impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> { .. } = self; - for (region, location, cause) in liveness_set { + for (region, location) in liveness_set { debug!("generate: {:#?} is live at {:#?}", region, location); let region_vid = regioncx.to_region_vid(region); - regioncx.add_live_point(region_vid, *location, &cause); + regioncx.add_live_point(region_vid, *location); } if let Some(all_facts) = all_facts { all_facts .region_live_at - .extend(liveness_set.into_iter().flat_map(|(region, location, _)| { + .extend(liveness_set.into_iter().flat_map(|(region, location)| { let r = regioncx.to_region_vid(region); let p1 = location_table.start_index(*location); let p2 = location_table.mid_index(*location); @@ -269,7 +269,7 @@ impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> { /// `location` -- i.e., it may be used later. This means that all /// regions appearing in the type `live_ty` must be live at /// `location`. - fn add_regular_live_constraint(&mut self, live_ty: T, location: Location, cause: Cause) + fn add_regular_live_constraint(&mut self, live_ty: T, location: Location) where T: TypeFoldable<'tcx>, { @@ -282,7 +282,7 @@ impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> { .tcx .for_each_free_region(&live_ty, |live_region| { let vid = live_region.to_region_vid(); - self.regioncx.add_live_point(vid, location, &cause); + self.regioncx.add_live_point(vid, location); }); } 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 index 58e9d814826..a65019690e3 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs @@ -8,50 +8,32 @@ // 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 std::collections::VecDeque; +use std::rc::Rc; + +use borrow_check::nll::region_infer::{Cause, RegionInferenceContext}; +use borrow_check::nll::ToRegionVid; use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor}; use rustc::mir::{Local, Location, Mir}; +use rustc::ty::{RegionVid, TyCtxt}; 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, +crate fn find<'cx, 'gcx: 'tcx, 'tcx: 'cx>( + mir: &'cx Mir<'tcx>, + regioncx: &'cx Rc>, + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + region_vid: RegionVid, start_point: Location, - local: Local, -) -> Option { +) -> Option { let mut uf = UseFinder { mir, regioncx, - borrow, + tcx, + region_vid, 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, }, }; @@ -59,23 +41,23 @@ crate fn drop_use<'gcx, 'tcx>( uf.find() } -struct UseFinder<'gcx, 'tcx> { - mir: &'gcx Mir<'gcx>, - regioncx: &'tcx RegionInferenceContext<'tcx>, - borrow: &'tcx BorrowData<'tcx>, +struct UseFinder<'cx, 'gcx: 'tcx, 'tcx: 'cx> { + mir: &'cx Mir<'tcx>, + regioncx: &'cx Rc>, + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + region_vid: RegionVid, start_point: Location, - local: Local, liveness_mode: LivenessMode, } -impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> { - fn find(&mut self) -> Option { - let mut stack = vec![]; +impl<'cx, 'gcx, 'tcx> UseFinder<'cx, 'gcx, 'tcx> { + fn find(&mut self) -> Option { + let mut queue = VecDeque::new(); 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) { + queue.push_back(self.start_point); + while let Some(p) = queue.pop_front() { + if !self.regioncx.region_contains_point(self.region_vid, p) { continue; } @@ -84,23 +66,36 @@ impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> { } 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, - } - })); + match self.def_use(p, block_data.visitable(p.statement_index)) { + Some(DefUseResult::Def) => {} + + Some(DefUseResult::UseLive { local }) => { + return Some(Cause::LiveVar(local, p)); + } + + Some(DefUseResult::UseDrop { local }) => { + return Some(Cause::DropVar(local, p)); + } + + None => { + if p.statement_index < block_data.statements.len() { + queue.push_back(Location { + statement_index: p.statement_index + 1, + ..p + }); + } else { + queue.extend( + block_data + .terminator() + .successors() + .filter(|&bb| Some(&Some(*bb)) != block_data.terminator().unwind()) + .map(|&bb| Location { + statement_index: 0, + block: bb, + }), + ); + } } } } @@ -108,34 +103,65 @@ impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> { None } - fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) { + fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option { let mut visitor = DefUseVisitor { - defined: false, - used: false, - local: self.local, + mir: self.mir, + tcx: self.tcx, + region_vid: self.region_vid, liveness_mode: self.liveness_mode, + def_use_result: None, }; thing.apply(location, &mut visitor); - (visitor.defined, visitor.used) + visitor.def_use_result } } -struct DefUseVisitor { - defined: bool, - used: bool, - local: Local, +struct DefUseVisitor<'cx, 'gcx: 'tcx, 'tcx: 'cx> { + mir: &'cx Mir<'tcx>, + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + region_vid: RegionVid, liveness_mode: LivenessMode, + def_use_result: Option, } -impl<'tcx> Visitor<'tcx> for DefUseVisitor { +enum DefUseResult { + Def, + + UseLive { local: Local }, + + UseDrop { local: Local }, +} + +impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for DefUseVisitor<'cx, 'gcx, 'tcx> { fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) { - if local == self.local { + let local_ty = self.mir.local_decls[local].ty; + + let mut found_it = false; + self.tcx.for_each_free_region(&local_ty, |r| { + if r.to_region_vid() == self.region_vid { + found_it = true; + } + }); + + if found_it { match liveness::categorize(context, self.liveness_mode) { - Some(DefUse::Def) => self.defined = true, - Some(DefUse::Use) => self.used = true, - None => (), + Some(DefUse::Def) => { + self.def_use_result = Some(DefUseResult::Def); + } + + Some(DefUse::Use) => { + self.def_use_result = if context.is_drop() { + Some(DefUseResult::UseDrop { local }) + } else { + Some(DefUseResult::UseLive { local }) + }; + } + + None => { + self.def_use_result = 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 acc164b14c3..bc4646b7c78 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -38,87 +38,72 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { kind_place: Option<(WriteKind, &Place<'tcx>)>, err: &mut DiagnosticBuilder<'_>, ) { - let regioncx = &&self.nonlexical_regioncx; + debug!( + "explain_why_borrow_contains_point(context={:?}, borrow={:?}, kind_place={:?})", + context, borrow, kind_place, + ); + + let regioncx = &self.nonlexical_regioncx; let mir = self.mir; + let tcx = self.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_use::regular_use( - mir, regioncx, borrow, location, local, - ) { - Some(p) => { - err.span_label(mir.source_info(p).span, format!("borrow later used here")); - } - None => { - span_bug!( - mir.source_info(context.loc).span, - "Cause should end in a LiveVar" - ); - } - }, + debug!( + "explain_why_borrow_contains_point: borrow_region_vid={:?}", + borrow_region_vid + ); - Cause::DropVar(local, location) => match find_use::drop_use( - mir, regioncx, borrow, location, local, - ) { - Some(p) => match &mir.local_decls[local].name { - Some(local_name) => { - err.span_label( - mir.source_info(p).span, - format!("borrow later used here, when `{}` is dropped", local_name), - ); + let region_sub = regioncx.find_constraint(borrow_region_vid, context.loc); - if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place { - if let Place::Local(borrowed_local) = place { - let dropped_local_scope = - mir.local_decls[local].visibility_scope; - let borrowed_local_scope = - mir.local_decls[*borrowed_local].visibility_scope; + debug!( + "explain_why_borrow_contains_point: region_sub={:?}", + region_sub + ); - if mir.is_sub_scope(borrowed_local_scope, dropped_local_scope) { - err.note( - "values in a scope are dropped \ - in the opposite order they are defined", - ); - } - } + match find_use::find(mir, regioncx, tcx, region_sub, context.loc) { + Some(Cause::LiveVar(_local, location)) => { + err.span_label( + mir.source_info(location).span, + format!("borrow later used here"), + ); + } + + Some(Cause::DropVar(local, location)) => match &mir.local_decls[local].name { + Some(local_name) => { + err.span_label( + mir.source_info(location).span, + format!("borrow later used here, when `{}` is dropped", local_name), + ); + + if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place { + if let Place::Local(borrowed_local) = place { + let dropped_local_scope = mir.local_decls[local].visibility_scope; + let borrowed_local_scope = + mir.local_decls[*borrowed_local].visibility_scope; + + if mir.is_sub_scope(borrowed_local_scope, dropped_local_scope) { + err.note( + "values in a scope are dropped \ + in the opposite order they are defined", + ); } } - None => { - err.span_label( - mir.local_decls[local].source_info.span, - "borrow may end up in a temporary, created here", - ); - - err.span_label( - mir.source_info(p).span, - "temporary later dropped here, \ - potentially using the reference", - ); - } - }, - - None => { - span_bug!( - mir.source_info(context.loc).span, - "Cause should end in a DropVar" - ); - } - }, - - Cause::UniversalRegion(region_vid) => { - if let Some(region) = regioncx.to_error_region(region_vid) { - self.tcx.note_and_explain_free_region( - err, - "borrowed value must be valid for ", - region, - "...", - ); } } - _ => {} + None => {} + }, + + None => { + if let Some(region) = regioncx.to_error_region(region_sub) { + self.tcx.note_and_explain_free_region( + err, + "borrowed value must be valid for ", + region, + "...", + ); + } } } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs index 970652d8872..6543516b9c2 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs @@ -9,7 +9,7 @@ // except according to those terms. use std::fmt; -use borrow_check::nll::region_infer::{Cause, ConstraintIndex, RegionInferenceContext}; +use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext}; use borrow_check::nll::region_infer::values::ToElementIndex; use borrow_check::nll::type_check::Locations; use rustc::hir::def_id::DefId; @@ -259,15 +259,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - crate fn why_region_contains_point(&self, fr1: RegionVid, elem: Location) -> Option { - // Find some constraint `X: Y` where: - // - `fr1: X` transitively - // - and `Y` is live at `elem` + // Find some constraint `X: Y` where: + // - `fr1: X` transitively + // - and `Y` is live at `elem` + crate fn find_constraint(&self, fr1: RegionVid, elem: Location) -> RegionVid { let index = self.blame_constraint(fr1, elem); - let region_sub = self.constraints[index].sub; - - // then return why `Y` was live at `elem` - self.liveness_constraints.cause(region_sub, elem) + self.constraints[index].sub } /// Tries to finds a good span to blame for the fact that `fr1` diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 014b37a0a27..fd6d79d160e 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -75,8 +75,6 @@ pub struct RegionInferenceContext<'tcx> { universal_regions: UniversalRegions<'tcx>, } -struct TrackCauses(bool); - struct RegionDefinition<'tcx> { /// Why we created this variable. Mostly these will be /// `RegionVariableOrigin::NLL`, but some variables get created @@ -105,13 +103,6 @@ pub(crate) enum Cause { /// point inserted because Local was dropped at the given Location DropVar(Local, Location), - - /// point inserted because the type was live at the given Location, - /// but not as part of some local variable - LiveOther(Location), - - /// part of the initial set of values for a universally quantified region - UniversalRegion(RegionVid), } /// A "type test" corresponds to an outlives constraint between a type @@ -283,7 +274,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.liveness_constraints.add_element( variable, point_index, - &Cause::UniversalRegion(variable), ); } @@ -291,7 +281,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.liveness_constraints.add_element( variable, variable, - &Cause::UniversalRegion(variable), ); } } @@ -337,13 +326,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// /// Returns `true` if this constraint is new and `false` is the /// constraint was already present. - pub(super) fn add_live_point(&mut self, v: RegionVid, point: Location, cause: &Cause) -> bool { + pub(super) fn add_live_point(&mut self, v: RegionVid, point: Location) -> bool { debug!("add_live_point({:?}, {:?})", v, point); assert!(self.inferred_values.is_none(), "values already inferred"); - debug!("add_live_point: @{:?} Adding cause {:?}", point, cause); let element = self.elements.index(point); - self.liveness_constraints.add_element(v, element, &cause) + self.liveness_constraints.add_element(v, element) } /// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`. @@ -436,7 +424,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // The initial values for each region are derived from the liveness // constraints we have accumulated. - let mut inferred_values = self.liveness_constraints.duplicate(TrackCauses(false)); + let mut inferred_values = self.liveness_constraints.clone(); let dependency_map = self.dependency_map.as_ref().unwrap(); diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index e914be52db0..5be4297f660 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -8,18 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use borrow_check::nll::region_infer::TrackCauses; use rustc::mir::{BasicBlock, Location, Mir}; use rustc::ty::RegionVid; use rustc_data_structures::bitvec::SparseBitMatrix; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::IndexVec; use std::fmt::Debug; use std::rc::Rc; -use super::Cause; - /// Maps between the various kinds of elements of a region value to /// the internal indices that w use. pub(super) struct RegionValueElements { @@ -180,19 +176,12 @@ impl ToElementIndex for RegionElementIndex { /// compact `SparseBitMatrix` representation, with one row per region /// variable. The columns consist of either universal regions or /// points in the CFG. +#[derive(Clone)] pub(super) struct RegionValues { elements: Rc, matrix: SparseBitMatrix, - - /// If cause tracking is enabled, maps from a pair (r, e) - /// consisting of a region `r` that contains some element `e` to - /// the reason that the element is contained. There should be an - /// entry for every bit set to 1 in `SparseBitMatrix`. - causes: Option, } -type CauseMap = FxHashMap<(RegionVid, RegionElementIndex), Cause>; - impl RegionValues { /// Creates a new set of "region values" that tracks causal information. /// Each of the regions in num_region_variables will be initialized with an @@ -209,25 +198,6 @@ impl RegionValues { RegionVid::new(num_region_variables), RegionElementIndex::new(elements.num_elements()), ), - causes: Some(CauseMap::default()), - } - } - - /// Duplicates the region values. If track_causes is false, then the - /// resulting value will not track causal information (and any existing - /// causal information is dropped). Otherwise, the causal information is - /// preserved and maintained. Tracking the causal information makes region - /// propagation significantly slower, so we prefer not to do it until an - /// error is reported. - pub(super) fn duplicate(&self, track_causes: TrackCauses) -> Self { - Self { - elements: self.elements.clone(), - matrix: self.matrix.clone(), - causes: if track_causes.0 { - self.causes.clone() - } else { - None - }, } } @@ -237,10 +207,10 @@ impl RegionValues { &mut self, r: RegionVid, elem: E, - cause: &Cause, ) -> bool { let i = self.elements.index(elem); - self.add_internal(r, i, |_| cause.clone()) + debug!("add(r={:?}, elem={:?})", r, elem); + self.matrix.add(r, i) } /// Add all elements in `r_from` to `r_to` (because e.g. `r_to: @@ -249,40 +219,6 @@ impl RegionValues { self.matrix.merge(r_from, r_to) } - /// Internal method to add an element to a region. - /// - /// Takes a "lazy" cause -- this function will return the cause, but it will only - /// be invoked if cause tracking is enabled. - fn add_internal(&mut self, r: RegionVid, i: RegionElementIndex, make_cause: F) -> bool - where - F: FnOnce(&CauseMap) -> Cause, - { - if self.matrix.add(r, i) { - debug!("add(r={:?}, i={:?})", r, self.elements.to_element(i)); - - if let Some(causes) = &mut self.causes { - let cause = make_cause(causes); - causes.insert((r, i), cause); - } - - true - } else { - if let Some(causes) = &mut self.causes { - let cause = make_cause(causes); - let old_cause = causes.get_mut(&(r, i)).unwrap(); - // #49998: compare using root cause alone to avoid - // useless traffic from similar outlives chains. - - if cause < *old_cause { - *old_cause = cause; - return true; - } - } - - false - } - } - /// True if the region `r` contains the given element. pub(super) fn contains(&self, r: RegionVid, elem: E) -> bool { let i = self.elements.index(elem); @@ -398,18 +334,4 @@ impl RegionValues { )); } } - - /// Given a region `r` that contains the element `elem`, returns the `Cause` - /// that tells us *why* `elem` is found in that region. - /// - /// Returns None if cause tracking is disabled or `elem` is not - /// actually found in `r`. - pub(super) fn cause(&self, r: RegionVid, elem: T) -> Option { - let index = self.elements.index(elem); - if let Some(causes) = &self.causes { - causes.get(&(r, index)).cloned() - } else { - None - } - } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs index d84dcc56782..dbdfef21970 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use borrow_check::nll::region_infer::Cause; use borrow_check::nll::type_check::AtLocation; use dataflow::move_paths::{HasMoveData, MoveData}; use dataflow::MaybeInitializedPlaces; @@ -88,8 +87,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo .simulate_block(self.mir, bb, |location, live_locals| { for live_local in live_locals.iter() { let live_local_ty = self.mir.local_decls[live_local].ty; - let cause = Cause::LiveVar(live_local, location); - Self::push_type_live_constraint(&mut self.cx, live_local_ty, location, cause); + Self::push_type_live_constraint(&mut self.cx, live_local_ty, location); } }); @@ -161,7 +159,6 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo cx: &mut TypeChecker<'_, 'gcx, 'tcx>, value: T, location: Location, - cause: Cause, ) where T: TypeFoldable<'tcx>, { @@ -173,7 +170,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo cx.tcx().for_each_free_region(&value, |live_region| { cx.constraints .liveness_set - .push((live_region, location, cause.clone())); + .push((live_region, location)); }); } @@ -210,9 +207,8 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo // All things in the `outlives` array may be touched by // the destructor and must be live at this point. - let cause = Cause::DropVar(dropped_local, location); for &kind in &drop_data.dropck_result.kinds { - Self::push_type_live_constraint(&mut self.cx, kind, location, cause); + Self::push_type_live_constraint(&mut self.cx, kind, location); } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index e3d20d9a8db..d5cf55c0f77 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -14,7 +14,6 @@ use borrow_check::location::LocationTable; use borrow_check::nll::constraint_set::ConstraintSet; use borrow_check::nll::facts::AllFacts; -use borrow_check::nll::region_infer::Cause; use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest}; use borrow_check::nll::universal_regions::UniversalRegions; use dataflow::move_paths::MoveData; @@ -615,7 +614,7 @@ crate struct MirTypeckRegionConstraints<'tcx> { /// not otherwise appear in the MIR -- in particular, the /// late-bound regions that it instantiates at call-sites -- and /// hence it must report on their liveness constraints. - crate liveness_set: Vec<(ty::Region<'tcx>, Location, Cause)>, + crate liveness_set: Vec<(ty::Region<'tcx>, Location)>, crate outlives_constraints: ConstraintSet, @@ -986,7 +985,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { self.constraints.liveness_set.push(( late_bound_region, term_location, - Cause::LiveOther(term_location), )); } diff --git a/src/test/ui/generator/borrowing.nll.stderr b/src/test/ui/generator/borrowing.nll.stderr index 243e9018585..015538b16f9 100644 --- a/src/test/ui/generator/borrowing.nll.stderr +++ b/src/test/ui/generator/borrowing.nll.stderr @@ -2,15 +2,10 @@ error[E0597]: `a` does not live long enough --> $DIR/borrowing.rs:18:18 | LL | unsafe { (|| yield &a).resume() } - | ^^^^^^^^^^^^^ - | | - | borrowed value does not live long enough - | borrow may end up in a temporary, created here + | ^^^^^^^^^^^^^ borrowed value does not live long enough LL | //~^ ERROR: `a` does not live long enough LL | }; - | -- temporary later dropped here, potentially using the reference - | | - | borrowed value only lives until here + | - borrowed value only lives until here error[E0597]: `a` does not live long enough --> $DIR/borrowing.rs:24:9 diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr index 70870b98365..08839c23c37 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr @@ -1,19 +1,11 @@ error[E0597]: `b` does not live long enough --> $DIR/ref-escapes-but-not-over-yield.rs:24:13 | -LL | let mut b = move || { - | _________________- -LL | | yield(); -LL | | let b = 5; -LL | | a = &b; - | | ^^ borrowed value does not live long enough -LL | | //~^ ERROR `b` does not live long enough -LL | | }; - | | - - | | | - | | borrowed value only lives until here - | |_____temporary later dropped here, potentially using the reference - | borrow may end up in a temporary, created here +LL | a = &b; + | ^^ borrowed value does not live long enough +LL | //~^ ERROR `b` does not live long enough +LL | }; + | - borrowed value only lives until here error: aborting due to previous error diff --git a/src/test/ui/issue-47646.stderr b/src/test/ui/issue-47646.stderr index b1289146e0e..4bdce85d18b 100644 --- a/src/test/ui/issue-47646.stderr +++ b/src/test/ui/issue-47646.stderr @@ -3,15 +3,9 @@ error[E0502]: cannot borrow `heap` as immutable because it is also borrowed as m | LL | let borrow = heap.peek_mut(); | ---- mutable borrow occurs here -LL | -LL | match (borrow, ()) { - | ------------ borrow may end up in a temporary, created here -LL | (Some(_), ()) => { +... LL | println!("{:?}", heap); //~ ERROR cannot borrow `heap` as immutable | ^^^^ immutable borrow occurs here -... -LL | }; - | - temporary later dropped here, potentially using the reference error: aborting due to previous error diff --git a/src/test/ui/span/destructor-restrictions.nll.stderr b/src/test/ui/span/destructor-restrictions.nll.stderr index 5de246cbb73..8be4cf445da 100644 --- a/src/test/ui/span/destructor-restrictions.nll.stderr +++ b/src/test/ui/span/destructor-restrictions.nll.stderr @@ -2,14 +2,9 @@ error[E0597]: `*a` does not live long enough --> $DIR/destructor-restrictions.rs:18:10 | LL | *a.borrow() + 1 - | ^--------- - | | - | borrowed value does not live long enough - | borrow may end up in a temporary, created here + | ^ borrowed value does not live long enough LL | }; //~^ ERROR `*a` does not live long enough - | -- temporary later dropped here, potentially using the reference - | | - | borrowed value only lives until here + | - borrowed value only lives until here error: aborting due to previous error diff --git a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.nll.stderr b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.nll.stderr index 56f2d14390e..ec2f5a25631 100644 --- a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.nll.stderr +++ b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.nll.stderr @@ -2,28 +2,17 @@ error[E0597]: `y` does not live long enough --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:20:5 | LL | y.borrow().clone() - | ^--------- - | | - | borrowed value does not live long enough - | borrow may end up in a temporary, created here + | ^ borrowed value does not live long enough LL | } - | - - | | - | borrowed value only lives until here - | temporary later dropped here, potentially using the reference + | - borrowed value only lives until here error[E0597]: `y` does not live long enough --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:27:9 | LL | y.borrow().clone() - | ^--------- - | | - | borrowed value does not live long enough - | borrow may end up in a temporary, created here + | ^ borrowed value does not live long enough LL | }; - | -- temporary later dropped here, potentially using the reference - | | - | borrowed value only lives until here + | - borrowed value only lives until here error: aborting due to 2 previous errors From 71f25b408de9da1fb8f6faec4fa833068f17978d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 28 Jun 2018 20:45:08 -0300 Subject: [PATCH 4/4] Run rustfmt --- .../borrow_check/nll/region_infer/mod.rs | 52 +++++++------------ .../borrow_check/nll/region_infer/values.rs | 12 ++--- .../borrow_check/nll/type_check/liveness.rs | 4 +- .../borrow_check/nll/type_check/mod.rs | 30 +++++------ 4 files changed, 40 insertions(+), 58 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index fd6d79d160e..13cc0c0419e 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -19,7 +19,7 @@ use rustc::infer::NLLRegionVariableOrigin; use rustc::infer::RegionVariableOrigin; use rustc::mir::{ ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location, - Mir + Mir, }; use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable}; use rustc::util::common; @@ -271,17 +271,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Add all nodes in the CFG to liveness constraints for point_index in self.elements.all_point_indices() { - self.liveness_constraints.add_element( - variable, - point_index, - ); + self.liveness_constraints.add_element(variable, point_index); } // Add `end(X)` into the set for X. - self.liveness_constraints.add_element( - variable, - variable, - ); + self.liveness_constraints.add_element(variable, variable); } } @@ -335,12 +329,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`. - pub(super) fn add_outlives( - &mut self, - locations: Locations, - sup: RegionVid, - sub: RegionVid, - ) { + pub(super) fn add_outlives(&mut self, locations: Locations, sup: RegionVid, sub: RegionVid) { assert!(self.inferred_values.is_none(), "values already inferred"); self.constraints.push(OutlivesConstraint { locations, @@ -445,11 +434,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("propagate_constraints: sub={:?}", constraint.sub); debug!("propagate_constraints: sup={:?}", constraint.sup); - self.constraints.each_affected_by_dirty(dependency_map[constraint.sup], |dep_idx| { - if clean_bit_vec.remove(dep_idx.index()) { - dirty_list.push(dep_idx); - } - }); + self.constraints.each_affected_by_dirty( + dependency_map[constraint.sup], + |dep_idx| { + if clean_bit_vec.remove(dep_idx.index()) { + dirty_list.push(dep_idx); + } + }, + ); } debug!("\n"); @@ -487,8 +479,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { } if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements { - if self.try_promote_type_test(infcx, mir, type_test, - propagated_outlives_requirements) { + if self.try_promote_type_test( + infcx, + mir, + type_test, + propagated_outlives_requirements, + ) { continue; } } @@ -744,12 +740,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Test if `test` is true when applied to `lower_bound` at /// `point`, and returns true or false. - fn eval_region_test( - &self, - mir: &Mir<'tcx>, - lower_bound: RegionVid, - test: &RegionTest, - ) -> bool { + fn eval_region_test(&self, mir: &Mir<'tcx>, lower_bound: RegionVid, test: &RegionTest) -> bool { debug!( "eval_region_test(lower_bound={:?}, test={:?})", lower_bound, test @@ -781,10 +772,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { sup_region: RegionVid, sub_region: RegionVid, ) -> bool { - debug!( - "eval_outlives({:?}: {:?})", - sup_region, sub_region - ); + debug!("eval_outlives({:?}: {:?})", sup_region, sub_region); let inferred_values = self .inferred_values diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index 5be4297f660..1039e6d7b97 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -28,7 +28,8 @@ pub(super) struct RegionValueElements { impl RegionValueElements { pub(super) fn new(mir: &Mir<'_>, num_universal_regions: usize) -> Self { let mut num_points = 0; - let statements_before_block = mir.basic_blocks() + let statements_before_block = mir + .basic_blocks() .iter() .map(|block_data| { let v = num_points; @@ -96,7 +97,8 @@ impl RegionValueElements { // be (BB2, 20). // // Nit: we could do a binary search here but I'm too lazy. - let (block, &first_index) = self.statements_before_block + let (block, &first_index) = self + .statements_before_block .iter_enumerated() .filter(|(_, first_index)| **first_index <= point_index) .last() @@ -203,11 +205,7 @@ impl RegionValues { /// Adds the given element to the value for the given region. Returns true if /// the element is newly added (i.e., was not already present). - pub(super) fn add_element( - &mut self, - r: RegionVid, - elem: E, - ) -> bool { + pub(super) fn add_element(&mut self, r: RegionVid, elem: E) -> bool { let i = self.elements.index(elem); debug!("add(r={:?}, elem={:?})", r, elem); self.matrix.add(r, i) diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs index dbdfef21970..91025e3f4af 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs @@ -168,9 +168,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo ); cx.tcx().for_each_free_region(&value, |live_region| { - cx.constraints - .liveness_set - .push((live_region, location)); + cx.constraints.liveness_set.push((live_region, location)); }); } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index d5cf55c0f77..2b47d50b4c2 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -311,7 +311,10 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { debug!("sanitize_constant: expected_ty={:?}", expected_ty); - if let Err(terr) = self.cx.eq_types(expected_ty, constant.ty, location.boring()) { + if let Err(terr) = self + .cx + .eq_types(expected_ty, constant.ty, location.boring()) + { span_mirbug!( self, constant, @@ -770,12 +773,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } - fn sub_types( - &mut self, - sub: Ty<'tcx>, - sup: Ty<'tcx>, - locations: Locations, - ) -> Fallible<()> { + fn sub_types(&mut self, sub: Ty<'tcx>, sup: Ty<'tcx>, locations: Locations) -> Fallible<()> { let param_env = self.param_env; self.fully_perform_op( locations, @@ -807,7 +805,11 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { false }; - let locations = if is_temp { location.boring() } else { location.interesting() }; + let locations = if is_temp { + location.boring() + } else { + location.interesting() + }; let place_ty = place.ty(mir, tcx).to_ty(tcx); let rv_ty = rv.ty(mir, tcx); @@ -982,10 +984,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // output) types in the signature must be live, since // all the inputs that fed into it were live. for &late_bound_region in map.values() { - self.constraints.liveness_set.push(( - late_bound_region, - term_location, - )); + self.constraints + .liveness_set + .push((late_bound_region, term_location)); } self.check_call_inputs(mir, term, &sig, args, term_location); @@ -1505,10 +1506,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ); // Hmm, are these constraints *really* boring? - self.push_region_constraints( - location.boring(), - &closure_constraints, - ); + self.push_region_constraints(location.boring(), &closure_constraints); } tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)