diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index 04f025fcbead9..3b7aac5c7f9f2 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -289,16 +289,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None => { if let Some(region) = regioncx.to_error_region_vid(borrow_region_vid) { - let (category, from_closure, span, region_name) = - self.nonlexical_regioncx.free_region_constraint_info( - &self.body, - &self.local_names, - &self.upvars, - self.mir_def_id, - self.infcx, - borrow_region_vid, - region, - ); + let (category, from_closure, span, region_name) = self + .nonlexical_regioncx + .free_region_constraint_info(self, borrow_region_vid, region); if let Some(region_name) = region_name { let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref()); BorrowExplanation::MustBeValidFor { diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index cd2138fdf94d3..5272054346e17 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -32,7 +32,7 @@ mod region_errors; crate use mutability_errors::AccessKind; crate use outlives_suggestion::OutlivesSuggestionBuilder; -crate use region_errors::{ErrorConstraintInfo, ErrorReportingCtx, RegionErrorKind, RegionErrors}; +crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors}; crate use region_name::{RegionErrorNamingCtx, RegionName, RegionNameSource}; pub(super) struct IncludingDowncast(pub(super) bool); diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs index 8acb2feeb70a9..1425c22e461cf 100644 --- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs +++ b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs @@ -4,20 +4,15 @@ use std::collections::BTreeMap; use log::debug; -use rustc::mir::{Body, Local}; -use rustc::{hir::def_id::DefId, infer::InferCtxt, ty::RegionVid}; +use rustc::ty::RegionVid; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Diagnostic, DiagnosticBuilder}; -use rustc_index::vec::IndexVec; -use syntax_pos::symbol::Symbol; +use rustc_errors::DiagnosticBuilder; use smallvec::SmallVec; -use crate::borrow_check::region_infer::RegionInferenceContext; +use crate::borrow_check::MirBorrowckCtxt; -use super::{ - ErrorConstraintInfo, ErrorReportingCtx, RegionErrorNamingCtx, RegionName, RegionNameSource, -}; +use super::{ErrorConstraintInfo, RegionErrorNamingCtx, RegionName, RegionNameSource}; /// The different things we could suggest. enum SuggestedConstraint { @@ -35,12 +30,8 @@ enum SuggestedConstraint { /// corresponding to a function definition. /// /// Adds a help note suggesting adding a where clause with the needed constraints. -pub struct OutlivesSuggestionBuilder<'a> { - /// The MIR DefId of the fn with the lifetime error. - mir_def_id: DefId, - - local_names: &'a IndexVec>, - +#[derive(Default)] +pub struct OutlivesSuggestionBuilder { /// The list of outlives constraints that need to be added. Specifically, we map each free /// region to all other regions that it must outlive. I will use the shorthand `fr: /// outlived_frs`. Not all of these regions will already have names necessarily. Some could be @@ -49,16 +40,7 @@ pub struct OutlivesSuggestionBuilder<'a> { constraints_to_add: BTreeMap>, } -impl OutlivesSuggestionBuilder<'a> { - /// Create a new builder for the given MIR node representing a fn definition. - crate fn new(mir_def_id: DefId, local_names: &'a IndexVec>) -> Self { - OutlivesSuggestionBuilder { - mir_def_id, - local_names, - constraints_to_add: BTreeMap::default(), - } - } - +impl OutlivesSuggestionBuilder { /// Returns `true` iff the `RegionNameSource` is a valid source for an outlives /// suggestion. // @@ -94,22 +76,19 @@ impl OutlivesSuggestionBuilder<'a> { /// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`. fn region_vid_to_name( &self, - errctx: &ErrorReportingCtx<'_, '_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_>, renctx: &mut RegionErrorNamingCtx, region: RegionVid, ) -> Option { - errctx - .region_infcx - .give_region_a_name(errctx, renctx, region) + mbcx.nonlexical_regioncx + .give_region_a_name(mbcx, renctx, region) .filter(Self::region_name_is_suggestable) } /// Compiles a list of all suggestions to be printed in the final big suggestion. - fn compile_all_suggestions<'tcx>( + fn compile_all_suggestions( &self, - body: &Body<'tcx>, - region_infcx: &RegionInferenceContext<'tcx>, - infcx: &InferCtxt<'_, 'tcx>, + mbcx: &MirBorrowckCtxt<'_, '_>, renctx: &mut RegionErrorNamingCtx, ) -> SmallVec<[SuggestedConstraint; 2]> { let mut suggested = SmallVec::new(); @@ -118,20 +97,8 @@ impl OutlivesSuggestionBuilder<'a> { // out silly duplicate messages. let mut unified_already = FxHashSet::default(); - let errctx = ErrorReportingCtx { - region_infcx, - infcx, - body, - mir_def_id: self.mir_def_id, - local_names: self.local_names, - - // We should not be suggesting naming upvars, so we pass in a dummy set of upvars that - // should never be used. - upvars: &[], - }; - for (fr, outlived) in &self.constraints_to_add { - let fr_name = if let Some(fr_name) = self.region_vid_to_name(&errctx, renctx, *fr) { + let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, renctx, *fr) { fr_name } else { continue; @@ -141,7 +108,7 @@ impl OutlivesSuggestionBuilder<'a> { .iter() // if there is a `None`, we will just omit that constraint .filter_map(|fr| { - self.region_vid_to_name(&errctx, renctx, *fr).map(|rname| (fr, rname)) + self.region_vid_to_name(mbcx, renctx, *fr).map(|rname| (fr, rname)) }) .collect::>(); @@ -204,14 +171,14 @@ impl OutlivesSuggestionBuilder<'a> { /// suggestable. crate fn intermediate_suggestion( &mut self, - errctx: &ErrorReportingCtx<'_, '_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, diag: &mut DiagnosticBuilder<'_>, ) { // Emit an intermediate note. - let fr_name = self.region_vid_to_name(errctx, renctx, errci.fr); - let outlived_fr_name = self.region_vid_to_name(errctx, renctx, errci.outlived_fr); + let fr_name = self.region_vid_to_name(mbcx, renctx, errci.fr); + let outlived_fr_name = self.region_vid_to_name(mbcx, renctx, errci.outlived_fr); if let (Some(fr_name), Some(outlived_fr_name)) = (fr_name, outlived_fr_name) { if let RegionNameSource::Static = outlived_fr_name.source { @@ -227,12 +194,9 @@ impl OutlivesSuggestionBuilder<'a> { /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final /// suggestion including all collected constraints. - crate fn add_suggestion<'tcx>( + crate fn add_suggestion( &self, - body: &Body<'tcx>, - region_infcx: &RegionInferenceContext<'tcx>, - infcx: &InferCtxt<'_, 'tcx>, - errors_buffer: &mut Vec, + mbcx: &mut MirBorrowckCtxt<'_, '_>, renctx: &mut RegionErrorNamingCtx, ) { // No constraints to add? Done. @@ -251,7 +215,7 @@ impl OutlivesSuggestionBuilder<'a> { } // Get all suggestable constraints. - let suggested = self.compile_all_suggestions(body, region_infcx, infcx, renctx); + let suggested = self.compile_all_suggestions(mbcx, renctx); // If there are no suggestable constraints... if suggested.is_empty() { @@ -262,7 +226,7 @@ impl OutlivesSuggestionBuilder<'a> { // If there is exactly one suggestable constraints, then just suggest it. Otherwise, emit a // list of diagnostics. let mut diag = if suggested.len() == 1 { - infcx.tcx.sess.diagnostic().struct_help(&match suggested.last().unwrap() { + mbcx.infcx.tcx.sess.diagnostic().struct_help(&match suggested.last().unwrap() { SuggestedConstraint::Outlives(a, bs) => { let bs: SmallVec<[String; 2]> = bs.iter().map(|r| format!("{}", r)).collect(); format!("add bound `{}: {}`", a, bs.join(" + ")) @@ -275,7 +239,8 @@ impl OutlivesSuggestionBuilder<'a> { }) } else { // Create a new diagnostic. - let mut diag = infcx + let mut diag = mbcx + .infcx .tcx .sess .diagnostic() @@ -305,10 +270,10 @@ impl OutlivesSuggestionBuilder<'a> { }; // We want this message to appear after other messages on the mir def. - let mir_span = infcx.tcx.def_span(self.mir_def_id); + let mir_span = mbcx.infcx.tcx.def_span(mbcx.mir_def_id); diag.sort_span = mir_span.shrink_to_hi(); // Buffer the diagnostic - diag.buffer(errors_buffer); + diag.buffer(&mut mbcx.errors_buffer); } } diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index e61581336283c..d560f7c517551 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -5,14 +5,13 @@ use rustc::infer::{ error_reporting::nice_region_error::NiceRegionError, region_constraints::GenericKind, InferCtxt, NLLRegionVariableOrigin, }; -use rustc::mir::{Body, ConstraintCategory, Local, Location}; +use rustc::mir::{Body, ConstraintCategory, Location}; use rustc::ty::{self, RegionVid, Ty}; use rustc_errors::DiagnosticBuilder; use rustc_index::vec::IndexVec; use std::collections::VecDeque; use syntax::errors::Applicability; use syntax::symbol::kw; -use syntax_pos::symbol::Symbol; use syntax_pos::Span; use crate::util::borrowck_errors; @@ -20,7 +19,7 @@ use crate::util::borrowck_errors; use crate::borrow_check::{ constraints::OutlivesConstraint, nll::ConstraintDescription, region_infer::RegionInferenceContext, type_check::Locations, universal_regions::DefiningTy, - Upvar, + MirBorrowckCtxt, }; use super::{OutlivesSuggestionBuilder, RegionErrorNamingCtx, RegionName, RegionNameSource}; @@ -116,27 +115,6 @@ crate enum RegionErrorKind<'tcx> { }, } -/// Various pieces of state used when reporting borrow checker errors. -pub struct ErrorReportingCtx<'a, 'b, 'tcx> { - /// The region inference context used for borrow chekcing this MIR body. - pub(super) region_infcx: &'b RegionInferenceContext<'tcx>, - - /// The inference context used for type checking. - pub(super) infcx: &'b InferCtxt<'a, 'tcx>, - - /// The MIR def we are reporting errors on. - pub(super) mir_def_id: DefId, - - /// The MIR body we are reporting errors on (for convenience). - pub(super) body: &'b Body<'tcx>, - - /// User variable names for MIR locals (where applicable). - pub(super) local_names: &'b IndexVec>, - - /// Any upvars for the MIR body we have kept track of during borrow checking. - pub(super) upvars: &'b [Upvar], -} - /// Information about the various region constraints involved in a borrow checker error. #[derive(Clone, Debug)] pub struct ErrorConstraintInfo { @@ -454,28 +432,24 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`. pub(in crate::borrow_check) fn report_error<'a>( &'a self, - body: &Body<'tcx>, - local_names: &IndexVec>, - upvars: &[Upvar], - infcx: &'a InferCtxt<'a, 'tcx>, - mir_def_id: DefId, + mbcx: &MirBorrowckCtxt<'a, 'tcx>, fr: RegionVid, fr_origin: NLLRegionVariableOrigin, outlived_fr: RegionVid, - outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>, + outlives_suggestion: &mut OutlivesSuggestionBuilder, renctx: &mut RegionErrorNamingCtx, ) -> DiagnosticBuilder<'a> { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); - let (category, _, span) = self.best_blame_constraint(body, fr, fr_origin, |r| { + let (category, _, span) = self.best_blame_constraint(&mbcx.body, fr, fr_origin, |r| { self.provides_universal_region(r, fr, outlived_fr) }); debug!("report_error: category={:?} {:?}", category, span); // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { - let tables = infcx.tcx.typeck_tables_of(mir_def_id); - let nice = NiceRegionError::new_from_span(infcx, span, o, f, Some(tables)); + let tables = mbcx.infcx.tcx.typeck_tables_of(mbcx.mir_def_id); + let nice = NiceRegionError::new_from_span(mbcx.infcx, span, o, f, Some(tables)); if let Some(diag) = nice.try_report_from_nll() { return diag; } @@ -491,9 +465,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr_is_local, outlived_fr_is_local, category ); - let errctx = - ErrorReportingCtx { region_infcx: self, infcx, mir_def_id, body, local_names, upvars }; - let errci = ErrorConstraintInfo { fr, outlived_fr, @@ -504,22 +475,22 @@ impl<'tcx> RegionInferenceContext<'tcx> { }; match (category, fr_is_local, outlived_fr_is_local) { - (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(infcx, fr) => { - self.report_fnmut_error(&errctx, &errci, renctx) + (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(mbcx.infcx, fr) => { + self.report_fnmut_error(mbcx, &errci, renctx) } (ConstraintCategory::Assignment, true, false) | (ConstraintCategory::CallArgument, true, false) => { - let mut db = self.report_escaping_data_error(&errctx, &errci, renctx); + let mut db = self.report_escaping_data_error(mbcx, &errci, renctx); - outlives_suggestion.intermediate_suggestion(&errctx, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(mbcx, &errci, renctx, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db } _ => { - let mut db = self.report_general_error(&errctx, &errci, renctx); + let mut db = self.report_general_error(mbcx, &errci, renctx); - outlives_suggestion.intermediate_suggestion(&errctx, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(mbcx, &errci, renctx, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db @@ -569,13 +540,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_fnmut_error( &self, - errctx: &ErrorReportingCtx<'_, '_, 'tcx>, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, ) -> DiagnosticBuilder<'_> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; - let mut diag = errctx + let mut diag = mbcx .infcx .tcx .sess @@ -593,7 +564,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { diag.span_label(*span, message); - match self.give_region_a_name(errctx, renctx, *outlived_fr).unwrap().source { + match self.give_region_a_name(mbcx, renctx, *outlived_fr).unwrap().source { RegionNameSource::NamedEarlyBoundRegion(fr_span) | RegionNameSource::NamedFreeRegion(fr_span) | RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _) @@ -630,21 +601,24 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_escaping_data_error( &self, - errctx: &ErrorReportingCtx<'_, '_, 'tcx>, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, ) -> DiagnosticBuilder<'_> { - let ErrorReportingCtx { infcx, body, upvars, local_names, .. } = errctx; - let ErrorConstraintInfo { span, category, .. } = errci; - let fr_name_and_span = - self.get_var_name_and_span_for_region(infcx.tcx, body, local_names, upvars, errci.fr); + let fr_name_and_span = self.get_var_name_and_span_for_region( + mbcx.infcx.tcx, + &mbcx.body, + &mbcx.local_names, + &mbcx.upvars, + errci.fr, + ); let outlived_fr_name_and_span = self.get_var_name_and_span_for_region( - infcx.tcx, - body, - local_names, - upvars, + mbcx.infcx.tcx, + &mbcx.body, + &mbcx.local_names, + &mbcx.upvars, errci.outlived_fr, ); @@ -662,14 +636,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { || escapes_from == "const" { return self.report_general_error( - errctx, + mbcx, &ErrorConstraintInfo { fr_is_local: true, outlived_fr_is_local: false, ..*errci }, renctx, ); } let mut diag = - borrowck_errors::borrowed_data_escapes_closure(infcx.tcx, *span, escapes_from); + borrowck_errors::borrowed_data_escapes_closure(mbcx.infcx.tcx, *span, escapes_from); if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span { diag.span_label( @@ -713,11 +687,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_general_error( &self, - errctx: &ErrorReportingCtx<'_, '_, 'tcx>, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, ) -> DiagnosticBuilder<'_> { - let ErrorReportingCtx { infcx, mir_def_id, .. } = errctx; let ErrorConstraintInfo { fr, fr_is_local, @@ -728,13 +701,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { .. } = errci; - let mut diag = infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); + let mut diag = + mbcx.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); - let mir_def_name = if infcx.tcx.is_closure(*mir_def_id) { "closure" } else { "function" }; + let mir_def_name = + if mbcx.infcx.tcx.is_closure(mbcx.mir_def_id) { "closure" } else { "function" }; - let fr_name = self.give_region_a_name(errctx, renctx, *fr).unwrap(); + let fr_name = self.give_region_a_name(mbcx, renctx, *fr).unwrap(); fr_name.highlight_region_name(&mut diag); - let outlived_fr_name = self.give_region_a_name(errctx, renctx, *outlived_fr).unwrap(); + let outlived_fr_name = self.give_region_a_name(mbcx, renctx, *outlived_fr).unwrap(); outlived_fr_name.highlight_region_name(&mut diag); match (category, outlived_fr_is_local, fr_is_local) { @@ -761,7 +736,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - self.add_static_impl_trait_suggestion(infcx, &mut diag, *fr, fr_name, *outlived_fr); + self.add_static_impl_trait_suggestion(mbcx.infcx, &mut diag, *fr, fr_name, *outlived_fr); diag } @@ -854,25 +829,19 @@ impl<'tcx> RegionInferenceContext<'tcx> { crate fn free_region_constraint_info( &self, - body: &Body<'tcx>, - local_names: &IndexVec>, - upvars: &[Upvar], - mir_def_id: DefId, - infcx: &InferCtxt<'_, 'tcx>, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, borrow_region: RegionVid, outlived_region: RegionVid, ) -> (ConstraintCategory, bool, Span, Option) { let (category, from_closure, span) = self.best_blame_constraint( - body, + &mbcx.body, borrow_region, NLLRegionVariableOrigin::FreeRegion, |r| self.provides_universal_region(r, borrow_region, outlived_region), ); let mut renctx = RegionErrorNamingCtx::new(); - let errctx = - ErrorReportingCtx { infcx, body, local_names, upvars, mir_def_id, region_infcx: self }; - let outlived_fr_name = self.give_region_a_name(&errctx, &mut renctx, outlived_region); + let outlived_fr_name = self.give_region_a_name(mbcx, &mut renctx, outlived_region); (category, from_closure, span, outlived_fr_name) } diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index 37e2b68692d5e..d92cee61c17a0 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -2,21 +2,17 @@ use std::fmt::{self, Display}; use rustc::hir; use rustc::hir::def::{DefKind, Res}; -use rustc::hir::def_id::DefId; -use rustc::infer::InferCtxt; -use rustc::mir::{Body, Local}; use rustc::ty::print::RegionHighlightMode; use rustc::ty::subst::{GenericArgKind, SubstsRef}; use rustc::ty::{self, RegionVid, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::DiagnosticBuilder; -use rustc_index::vec::IndexVec; use syntax::symbol::kw; use syntax_pos::{symbol::Symbol, Span, DUMMY_SP}; use crate::borrow_check::{ - diagnostics::region_errors::ErrorReportingCtx, nll::ToRegionVid, - region_infer::RegionInferenceContext, universal_regions::DefiningTy, Upvar, + nll::ToRegionVid, region_infer::RegionInferenceContext, universal_regions::DefiningTy, + MirBorrowckCtxt, }; /// A name for a particular region used in emitting diagnostics. This name could be a generated @@ -193,12 +189,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// and then return the name `'1` for us to use. crate fn give_region_a_name( &self, - errctx: &ErrorReportingCtx<'_, '_, 'tcx>, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, renctx: &mut RegionErrorNamingCtx, fr: RegionVid, ) -> Option { - let ErrorReportingCtx { infcx, body, mir_def_id, local_names, upvars, .. } = errctx; - debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); assert!(self.universal_regions.is_universal_region(fr)); @@ -208,38 +202,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { } let value = self - .give_name_from_error_region(infcx.tcx, *mir_def_id, fr, renctx) - .or_else(|| { - self.give_name_if_anonymous_region_appears_in_arguments( - infcx, - body, - local_names, - *mir_def_id, - fr, - renctx, - ) - }) - .or_else(|| { - self.give_name_if_anonymous_region_appears_in_upvars(infcx.tcx, upvars, fr, renctx) - }) - .or_else(|| { - self.give_name_if_anonymous_region_appears_in_output( - infcx, - body, - *mir_def_id, - fr, - renctx, - ) - }) - .or_else(|| { - self.give_name_if_anonymous_region_appears_in_yield_ty( - infcx, - body, - *mir_def_id, - fr, - renctx, - ) - }); + .give_name_from_error_region(mbcx, fr, renctx) + .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(mbcx, fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(mbcx, fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_output(mbcx, fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(mbcx, fr, renctx)); if let Some(ref value) = value { renctx.insert(fr, value.clone()); @@ -255,8 +222,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// named variants. fn give_name_from_error_region( &self, - tcx: TyCtxt<'tcx>, - mir_def_id: DefId, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { @@ -266,7 +232,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { match error_region { ty::ReEarlyBound(ebr) => { if ebr.has_name() { - let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); + let span = mbcx.infcx.tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); Some(RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyBoundRegion(span), @@ -283,7 +249,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { ty::ReFree(free_region) => match free_region.bound_region { ty::BoundRegion::BrNamed(region_def_id, name) => { // Get the span to point to, even if we don't use the name. - let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP); + let span = + mbcx.infcx.tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP); debug!( "bound region named: {:?}, is_named: {:?}", name, @@ -308,12 +275,17 @@ impl<'tcx> RegionInferenceContext<'tcx> { } ty::BoundRegion::BrEnv => { - let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir"); + let mir_hir_id = mbcx + .infcx + .tcx + .hir() + .as_local_hir_id(mbcx.mir_def_id) + .expect("non-local mir"); let def_ty = self.universal_regions.defining_ty; if let DefiningTy::Closure(def_id, substs) = def_ty { let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) = - tcx.hir().expect_expr(mir_hir_id).kind + mbcx.infcx.tcx.hir().expect_expr(mir_hir_id).kind { span } else { @@ -321,7 +293,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }; let region_name = renctx.synthesize_region_name(); - let closure_kind_ty = substs.as_closure().kind_ty(def_id, tcx); + let closure_kind_ty = substs.as_closure().kind_ty(def_id, mbcx.infcx.tcx); let note = match closure_kind_ty.to_opt_closure_kind() { Some(ty::ClosureKind::Fn) => { "closure implements `Fn`, so references to captured variables \ @@ -373,21 +345,17 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_anonymous_region_appears_in_arguments( &self, - infcx: &InferCtxt<'_, 'tcx>, - body: &Body<'tcx>, - local_names: &IndexVec>, - mir_def_id: DefId, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); - let argument_index = self.get_argument_index_for_region(infcx.tcx, fr)?; + let argument_index = self.get_argument_index_for_region(mbcx.infcx.tcx, fr)?; let arg_ty = self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index]; if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument( - infcx, - mir_def_id, + mbcx, fr, arg_ty, argument_index, @@ -396,20 +364,19 @@ impl<'tcx> RegionInferenceContext<'tcx> { return Some(region_name); } - self.give_name_if_we_cannot_match_hir_ty(infcx, body, local_names, fr, arg_ty, renctx) + self.give_name_if_we_cannot_match_hir_ty(mbcx, fr, arg_ty, renctx) } fn give_name_if_we_can_match_hir_ty_from_argument( &self, - infcx: &InferCtxt<'_, 'tcx>, - mir_def_id: DefId, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_index: usize, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let mir_hir_id = infcx.tcx.hir().as_local_hir_id(mir_def_id)?; - let fn_decl = infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?; + let mir_hir_id = mbcx.infcx.tcx.hir().as_local_hir_id(mbcx.mir_def_id)?; + let fn_decl = mbcx.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?; let argument_hir_ty: &hir::Ty<'_> = fn_decl.inputs.get(argument_index)?; match argument_hir_ty.kind { // This indicates a variable with no type annotation, like @@ -420,7 +387,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { hir::TyKind::Infer => None, _ => self.give_name_if_we_can_match_hir_ty( - infcx.tcx, + mbcx.infcx.tcx, needle_fr, argument_ty, argument_hir_ty, @@ -442,9 +409,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_we_cannot_match_hir_ty( &self, - infcx: &InferCtxt<'_, 'tcx>, - body: &Body<'tcx>, - local_names: &IndexVec>, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, needle_fr: RegionVid, argument_ty: Ty<'tcx>, renctx: &mut RegionErrorNamingCtx, @@ -452,7 +417,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let counter = renctx.counter; let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(needle_fr, counter); - let type_name = infcx.extract_type_name(&argument_ty, Some(highlight)).0; + let type_name = mbcx.infcx.extract_type_name(&argument_ty, Some(highlight)).0; debug!( "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}", @@ -460,9 +425,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { ); let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() { // Only add a label if we can confirm that a region was labelled. - let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?; - let (_, span) = - self.get_argument_name_and_span_for_region(body, local_names, argument_index); + let argument_index = self.get_argument_index_for_region(mbcx.infcx.tcx, needle_fr)?; + let (_, span) = self.get_argument_name_and_span_for_region( + &mbcx.body, + &mbcx.local_names, + argument_index, + ); Some(RegionName { // This counter value will already have been used, so this function will increment @@ -696,14 +664,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_anonymous_region_appears_in_upvars( &self, - tcx: TyCtxt<'tcx>, - upvars: &[Upvar], + mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let upvar_index = self.get_upvar_index_for_region(tcx, fr)?; + let upvar_index = self.get_upvar_index_for_region(mbcx.infcx.tcx, fr)?; let (upvar_name, upvar_span) = - self.get_upvar_name_and_span_for_region(tcx, upvars, upvar_index); + self.get_upvar_name_and_span_for_region(mbcx.infcx.tcx, &mbcx.upvars, upvar_index); let region_name = renctx.synthesize_region_name(); Some(RegionName { @@ -718,13 +685,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// or be early bound (named, not in argument). fn give_name_if_anonymous_region_appears_in_output( &self, - infcx: &InferCtxt<'_, 'tcx>, - body: &Body<'tcx>, - mir_def_id: DefId, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let tcx = infcx.tcx; + let tcx = mbcx.infcx.tcx; let return_ty = self.universal_regions.unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); @@ -734,9 +699,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(fr, renctx.counter); - let type_name = infcx.extract_type_name(&return_ty, Some(highlight)).0; + let type_name = mbcx.infcx.extract_type_name(&return_ty, Some(highlight)).0; - let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir"); + let mir_hir_id = tcx.hir().as_local_hir_id(mbcx.mir_def_id).expect("non-local mir"); let (return_span, mir_description) = match tcx.hir().get(mir_hir_id) { hir::Node::Expr(hir::Expr { @@ -753,7 +718,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { kind: hir::ImplItemKind::Method(method_sig, _), .. }) => (method_sig.decl.output.span(), ""), - _ => (body.span, ""), + _ => (mbcx.body.span, ""), }; Some(RegionName { @@ -771,9 +736,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn give_name_if_anonymous_region_appears_in_yield_ty( &self, - infcx: &InferCtxt<'_, 'tcx>, - body: &Body<'tcx>, - mir_def_id: DefId, + mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { @@ -782,7 +745,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let yield_ty = self.universal_regions.yield_ty?; debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,); - let tcx = infcx.tcx; + let tcx = mbcx.infcx.tcx; if !tcx.any_free_region_meets(&yield_ty, |r| r.to_region_vid() == fr) { return None; @@ -790,15 +753,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(fr, renctx.counter); - let type_name = infcx.extract_type_name(&yield_ty, Some(highlight)).0; + let type_name = mbcx.infcx.extract_type_name(&yield_ty, Some(highlight)).0; - let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir"); + let mir_hir_id = tcx.hir().as_local_hir_id(mbcx.mir_def_id).expect("non-local mir"); let yield_span = match tcx.hir().get(mir_hir_id) { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, _, _, span, _), .. }) => (tcx.sess.source_map().end_point(*span)), - _ => body.span, + _ => mbcx.body.span, }; debug!( diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index a03ac3c33a97b..59e6b0bb14ea3 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1482,8 +1482,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // FIXME(mark-i-m): Would be great to get rid of the naming context. let mut region_naming = RegionErrorNamingCtx::new(); - let mut outlives_suggestion = - OutlivesSuggestionBuilder::new(self.mir_def_id, &self.local_names); + let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); for nll_error in nll_errors.into_iter() { match nll_error { @@ -1561,11 +1560,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { if is_reported { let db = self.nonlexical_regioncx.report_error( - &self.body, - &self.local_names, - &self.upvars, - self.infcx, - self.mir_def_id, + self, longer_fr, fr_origin, shorter_fr, @@ -1591,13 +1586,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } // Emit one outlives suggestions for each MIR def we borrowck - outlives_suggestion.add_suggestion( - &self.body, - &self.nonlexical_regioncx, - self.infcx, - &mut self.errors_buffer, - &mut region_naming, - ); + outlives_suggestion.add_suggestion(self, &mut region_naming); } }