mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
Get rid of ErrorReportingCtx
This commit is contained in:
parent
2ba0d2acbd
commit
eb218fc8f0
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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!(
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user