Get rid of ErrorReportingCtx

This commit is contained in:
mark 2019-12-20 23:59:31 -06:00
parent 2ba0d2acbd
commit eb218fc8f0
6 changed files with 122 additions and 243 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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<Local, Option<Symbol>>,
#[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<RegionVid, Vec<RegionVid>>,
}
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<Local, Option<Symbol>>) -> 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<RegionName> {
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::<Vec<_>>();
@ -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<Diagnostic>,
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);
}
}

View File

@ -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<Local, Option<Symbol>>,
/// 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<Local, Option<Symbol>>,
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<Local, Option<Symbol>>,
upvars: &[Upvar],
mir_def_id: DefId,
infcx: &InferCtxt<'_, 'tcx>,
mbcx: &MirBorrowckCtxt<'_, 'tcx>,
borrow_region: RegionVid,
outlived_region: RegionVid,
) -> (ConstraintCategory, bool, Span, Option<RegionName>) {
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)
}

View File

@ -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<RegionName> {
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<RegionName> {
@ -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<Local, Option<Symbol>>,
mir_def_id: DefId,
mbcx: &MirBorrowckCtxt<'_, 'tcx>,
fr: RegionVid,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
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<RegionName> {
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<Local, Option<Symbol>>,
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<RegionName> {
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<RegionName> {
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<RegionName> {
@ -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!(

View File

@ -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);
}
}