提交 a804868b 编写于 作者: M Mark Mansi 提交者: mark

Get rid of RegionErrorNamingContext

上级 234b9301
......@@ -16,8 +16,8 @@
use rustc_span::Span;
use crate::borrow_check::{
borrow_set::BorrowData, diagnostics::RegionErrorNamingCtx, nll::ConstraintDescription,
region_infer::Cause, MirBorrowckCtxt, WriteKind,
borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt,
WriteKind,
};
use super::{find_use, RegionName, UseSpans};
......@@ -267,8 +267,7 @@ fn free_region_constraint_info(
|r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region),
);
let mut renctx = RegionErrorNamingCtx::new();
let outlived_fr_name = self.give_region_a_name(&mut renctx, outlived_region);
let outlived_fr_name = self.give_region_a_name(outlived_region);
(category, from_closure, span, outlived_fr_name)
}
......
......@@ -32,7 +32,7 @@
crate use mutability_errors::AccessKind;
crate use outlives_suggestion::OutlivesSuggestionBuilder;
crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
crate use region_name::{RegionErrorNamingCtx, RegionName, RegionNameSource};
crate use region_name::{RegionName, RegionNameSource};
pub(super) struct IncludingDowncast(pub(super) bool);
......
......@@ -12,7 +12,7 @@
use crate::borrow_check::MirBorrowckCtxt;
use super::{ErrorConstraintInfo, RegionErrorNamingCtx, RegionName, RegionNameSource};
use super::{ErrorConstraintInfo, RegionName, RegionNameSource};
/// The different things we could suggest.
enum SuggestedConstraint {
......@@ -77,17 +77,15 @@ fn region_name_is_suggestable(name: &RegionName) -> bool {
fn region_vid_to_name(
&self,
mbcx: &MirBorrowckCtxt<'_, '_>,
renctx: &mut RegionErrorNamingCtx,
region: RegionVid,
) -> Option<RegionName> {
mbcx.give_region_a_name(renctx, region).filter(Self::region_name_is_suggestable)
mbcx.give_region_a_name(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(
&self,
mbcx: &MirBorrowckCtxt<'_, '_>,
renctx: &mut RegionErrorNamingCtx,
) -> SmallVec<[SuggestedConstraint; 2]> {
let mut suggested = SmallVec::new();
......@@ -96,7 +94,7 @@ fn compile_all_suggestions(
let mut unified_already = FxHashSet::default();
for (fr, outlived) in &self.constraints_to_add {
let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, renctx, *fr) {
let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, *fr) {
fr_name
} else {
continue;
......@@ -105,9 +103,7 @@ fn compile_all_suggestions(
let outlived = outlived
.iter()
// if there is a `None`, we will just omit that constraint
.filter_map(|fr| {
self.region_vid_to_name(mbcx, renctx, *fr).map(|rname| (fr, rname))
})
.filter_map(|fr| self.region_vid_to_name(mbcx, *fr).map(|rname| (fr, rname)))
.collect::<Vec<_>>();
// No suggestable outlived lifetimes.
......@@ -171,12 +167,11 @@ fn compile_all_suggestions(
&mut self,
mbcx: &MirBorrowckCtxt<'_, '_>,
errci: &ErrorConstraintInfo,
renctx: &mut RegionErrorNamingCtx,
diag: &mut DiagnosticBuilder<'_>,
) {
// Emit an intermediate note.
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);
let fr_name = self.region_vid_to_name(mbcx, errci.fr);
let outlived_fr_name = self.region_vid_to_name(mbcx, 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 {
......@@ -192,11 +187,7 @@ fn compile_all_suggestions(
/// 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(
&self,
mbcx: &mut MirBorrowckCtxt<'_, '_>,
renctx: &mut RegionErrorNamingCtx,
) {
crate fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) {
// No constraints to add? Done.
if self.constraints_to_add.is_empty() {
debug!("No constraints to suggest.");
......@@ -213,7 +204,7 @@ fn compile_all_suggestions(
}
// Get all suggestable constraints.
let suggested = self.compile_all_suggestions(mbcx, renctx);
let suggested = self.compile_all_suggestions(mbcx);
// If there are no suggestable constraints...
if suggested.is_empty() {
......
......@@ -19,7 +19,7 @@
MirBorrowckCtxt,
};
use super::{OutlivesSuggestionBuilder, RegionErrorNamingCtx, RegionName, RegionNameSource};
use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource};
impl ConstraintDescription for ConstraintCategory {
fn description(&self) -> &'static str {
......@@ -152,8 +152,6 @@ pub(in crate::borrow_check) fn report_region_errors(&mut self, nll_errors: Regio
// Iterate through all the errors, producing a diagnostic for each one. The diagnostics are
// buffered in the `MirBorrowckCtxt`.
// TODO(mark-i-m): Would be great to get rid of the naming context.
let mut region_naming = RegionErrorNamingCtx::new();
let mut outlives_suggestion = OutlivesSuggestionBuilder::default();
for nll_error in nll_errors.into_iter() {
......@@ -243,7 +241,6 @@ pub(in crate::borrow_check) fn report_region_errors(&mut self, nll_errors: Regio
fr_origin,
shorter_fr,
&mut outlives_suggestion,
&mut region_naming,
);
} else {
// We only report the first error, so as not to overwhelm the user. See
......@@ -262,7 +259,7 @@ pub(in crate::borrow_check) fn report_region_errors(&mut self, nll_errors: Regio
}
// Emit one outlives suggestions for each MIR def we borrowck
outlives_suggestion.add_suggestion(self, &mut region_naming);
outlives_suggestion.add_suggestion(self);
}
/// Report an error because the universal region `fr` was required to outlive
......@@ -279,7 +276,6 @@ pub(in crate::borrow_check) fn report_error(
fr_origin: NLLRegionVariableOrigin,
outlived_fr: RegionVid,
outlives_suggestion: &mut OutlivesSuggestionBuilder,
renctx: &mut RegionErrorNamingCtx,
) {
debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
......@@ -320,21 +316,21 @@ pub(in crate::borrow_check) fn report_error(
let diag = match (category, fr_is_local, outlived_fr_is_local) {
(ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(fr) => {
self.report_fnmut_error(&errci, renctx)
self.report_fnmut_error(&errci)
}
(ConstraintCategory::Assignment, true, false)
| (ConstraintCategory::CallArgument, true, false) => {
let mut db = self.report_escaping_data_error(&errci, renctx);
let mut db = self.report_escaping_data_error(&errci);
outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db);
outlives_suggestion.intermediate_suggestion(self, &errci, &mut db);
outlives_suggestion.collect_constraint(fr, outlived_fr);
db
}
_ => {
let mut db = self.report_general_error(&errci, renctx);
let mut db = self.report_general_error(&errci);
outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db);
outlives_suggestion.intermediate_suggestion(self, &errci, &mut db);
outlives_suggestion.collect_constraint(fr, outlived_fr);
db
......@@ -360,11 +356,7 @@ pub(in crate::borrow_check) fn report_error(
/// executing...
/// = note: ...therefore, returned references to captured variables will escape the closure
/// ```
fn report_fnmut_error(
&self,
errci: &ErrorConstraintInfo,
renctx: &mut RegionErrorNamingCtx,
) -> DiagnosticBuilder<'tcx> {
fn report_fnmut_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
let mut diag = self
......@@ -386,7 +378,7 @@ fn report_fnmut_error(
diag.span_label(*span, message);
match self.give_region_a_name(renctx, *outlived_fr).unwrap().source {
match self.give_region_a_name(*outlived_fr).unwrap().source {
RegionNameSource::NamedEarlyBoundRegion(fr_span)
| RegionNameSource::NamedFreeRegion(fr_span)
| RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _)
......@@ -421,11 +413,7 @@ fn report_fnmut_error(
/// LL | ref_obj(x)
/// | ^^^^^^^^^^ `x` escapes the function body here
/// ```
fn report_escaping_data_error(
&self,
errci: &ErrorConstraintInfo,
renctx: &mut RegionErrorNamingCtx,
) -> DiagnosticBuilder<'tcx> {
fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> {
let ErrorConstraintInfo { span, category, .. } = errci;
let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region(
......@@ -456,10 +444,11 @@ fn report_escaping_data_error(
|| (*category == ConstraintCategory::Assignment && escapes_from == "function")
|| escapes_from == "const"
{
return self.report_general_error(
&ErrorConstraintInfo { fr_is_local: true, outlived_fr_is_local: false, ..*errci },
renctx,
);
return self.report_general_error(&ErrorConstraintInfo {
fr_is_local: true,
outlived_fr_is_local: false,
..*errci
});
}
let mut diag =
......@@ -505,11 +494,7 @@ fn report_escaping_data_error(
/// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it
/// | is returning data with lifetime `'b`
/// ```
fn report_general_error(
&self,
errci: &ErrorConstraintInfo,
renctx: &mut RegionErrorNamingCtx,
) -> DiagnosticBuilder<'tcx> {
fn report_general_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> {
let ErrorConstraintInfo {
fr,
fr_is_local,
......@@ -526,9 +511,9 @@ fn report_general_error(
let mir_def_name =
if self.infcx.tcx.is_closure(self.mir_def_id) { "closure" } else { "function" };
let fr_name = self.give_region_a_name(renctx, *fr).unwrap();
let fr_name = self.give_region_a_name(*fr).unwrap();
fr_name.highlight_region_name(&mut diag);
let outlived_fr_name = self.give_region_a_name(renctx, *outlived_fr).unwrap();
let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap();
outlived_fr_name.highlight_region_name(&mut diag);
match (category, outlived_fr_is_local, fr_is_local) {
......
......@@ -3,7 +3,6 @@
use rustc::ty::print::RegionHighlightMode;
use rustc::ty::subst::{GenericArgKind, SubstsRef};
use rustc::ty::{self, RegionVid, Ty};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::DiagnosticBuilder;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
......@@ -52,46 +51,6 @@
AnonRegionFromAsyncFn(Span),
}
/// Records region names that have been assigned before so that we can use the same ones in later
/// diagnostics.
#[derive(Debug, Clone)]
crate struct RegionErrorNamingCtx {
/// Record the region names generated for each region in the given
/// MIR def so that we can reuse them later in help/error messages.
renctx: FxHashMap<RegionVid, RegionName>,
/// The counter for generating new region names.
counter: usize,
}
impl RegionErrorNamingCtx {
crate fn new() -> Self {
Self { counter: 1, renctx: FxHashMap::default() }
}
/// Get the name of `region` if it has previously been named.
crate fn get(&self, region: &RegionVid) -> Option<&RegionName> {
self.renctx.get(region)
}
/// Give `region` the name `name`.
crate fn insert(&mut self, region: RegionVid, name: RegionName) {
self.renctx.insert(region, name);
}
/// Creates a synthetic region named `'N`, where `N` is the next value of the counter. Then,
/// increment the counter.
///
/// The name is not memoized. A separate call to `insert` should be made later. (Currently,
/// this happens at the end of `give_region_a_name`).
crate fn synthesize_region_name(&mut self) -> Symbol {
let c = self.counter;
self.counter += 1;
Symbol::intern(&format!("'{:?}", c))
}
}
impl RegionName {
crate fn was_named(&self) -> bool {
match self.source {
......@@ -159,6 +118,17 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// Generate a synthetic region named `'N`, where `N` is the next value of the counter. Then,
/// increment the counter.
///
/// This is _not_ idempotent. Call `give_region_a_name` when possible.
fn synthesize_region_name(&self) -> Symbol {
let mut counter = self.next_region_name.try_borrow_mut().unwrap();
let c = *counter;
*counter += 1;
Symbol::intern(&format!("'{:?}", c))
}
/// Maps from an internal MIR region vid to something that we can
/// report to the user. In some cases, the region vids will map
/// directly to lifetimes that the user has a name for (e.g.,
......@@ -167,6 +137,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// that end, this function takes a "diagnostic" so that it can
/// create auxiliary notes as needed.
///
/// The names are memoized, so this is both cheap to recompute and idempotent.
///
/// Example (function arguments):
///
/// Suppose we are trying to give a name to the lifetime of the
......@@ -184,28 +156,28 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// ```
///
/// and then return the name `'1` for us to use.
crate fn give_region_a_name(
&self,
renctx: &mut RegionErrorNamingCtx,
fr: RegionVid,
) -> Option<RegionName> {
debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter);
crate fn give_region_a_name(&self, fr: RegionVid) -> Option<RegionName> {
debug!(
"give_region_a_name(fr={:?}, counter={:?})",
fr,
self.next_region_name.try_borrow().unwrap()
);
assert!(self.regioncx.universal_regions().is_universal_region(fr));
if let Some(value) = renctx.get(&fr) {
if let Some(value) = self.region_names.try_borrow_mut().unwrap().get(&fr) {
return Some(value.clone());
}
let value = self
.give_name_from_error_region(fr, renctx)
.or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr, renctx))
.or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr, renctx))
.or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr, renctx))
.or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr, renctx));
.give_name_from_error_region(fr)
.or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr));
if let Some(ref value) = value {
renctx.insert(fr, value.clone());
self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
}
debug!("give_region_a_name: gave name {:?}", value);
......@@ -216,11 +188,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// *user* has a name for. In that case, we'll be able to map
/// `fr` to a `Region<'tcx>`, and that region will be one of
/// named variants.
fn give_name_from_error_region(
&self,
fr: RegionVid,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
fn give_name_from_error_region(&self, fr: RegionVid) -> Option<RegionName> {
let error_region = self.to_error_region(fr)?;
let tcx = self.infcx.tcx;
......@@ -262,7 +230,7 @@ fn give_name_from_error_region(
// happen if we have an elided name in an async fn for example: the
// compiler will generate a region named `'_`, but reporting such a name is
// not actually useful, so we synthesize a name for it instead.
let name = renctx.synthesize_region_name();
let name = self.synthesize_region_name();
Some(RegionName {
name,
source: RegionNameSource::AnonRegionFromAsyncFn(span),
......@@ -287,7 +255,7 @@ fn give_name_from_error_region(
} else {
bug!("Closure is not defined by a closure expr");
};
let region_name = renctx.synthesize_region_name();
let region_name = self.synthesize_region_name();
let closure_kind_ty = substs.as_closure().kind_ty(def_id, tcx);
let note = match closure_kind_ty.to_opt_closure_kind() {
......@@ -342,7 +310,6 @@ fn give_name_from_error_region(
fn give_name_if_anonymous_region_appears_in_arguments(
&self,
fr: RegionVid,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
let implicit_inputs = self.regioncx.universal_regions().defining_ty.implicit_inputs();
let argument_index = self.regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?;
......@@ -350,12 +317,12 @@ fn give_name_if_anonymous_region_appears_in_arguments(
let arg_ty = self.regioncx.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(fr, arg_ty, argument_index, renctx)
self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index)
{
return Some(region_name);
}
self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty, renctx)
self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty)
}
fn give_name_if_we_can_match_hir_ty_from_argument(
......@@ -363,7 +330,6 @@ fn give_name_if_we_can_match_hir_ty_from_argument(
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
argument_index: usize,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
let mir_hir_id = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id)?;
let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?;
......@@ -376,12 +342,7 @@ fn give_name_if_we_can_match_hir_ty_from_argument(
// (`give_name_if_anonymous_region_appears_in_arguments`).
hir::TyKind::Infer => None,
_ => self.give_name_if_we_can_match_hir_ty(
needle_fr,
argument_ty,
argument_hir_ty,
renctx,
),
_ => self.give_name_if_we_can_match_hir_ty(needle_fr, argument_ty, argument_hir_ty),
}
}
......@@ -400,9 +361,8 @@ fn give_name_if_we_cannot_match_hir_ty(
&self,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
let counter = renctx.counter;
let counter = *self.next_region_name.try_borrow().unwrap();
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(needle_fr, counter);
let type_name = self.infcx.extract_type_name(&argument_ty, Some(highlight)).0;
......@@ -425,7 +385,7 @@ fn give_name_if_we_cannot_match_hir_ty(
// This counter value will already have been used, so this function will increment
// it so the next value will be used next and return the region name that would
// have been used.
name: renctx.synthesize_region_name(),
name: self.synthesize_region_name(),
source: RegionNameSource::CannotMatchHirTy(span, type_name),
})
} else {
......@@ -461,7 +421,6 @@ fn give_name_if_we_can_match_hir_ty(
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
argument_hir_ty: &hir::Ty<'_>,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty<'_>)> =
&mut vec![(argument_ty, argument_hir_ty)];
......@@ -479,7 +438,7 @@ fn give_name_if_we_can_match_hir_ty(
hir::TyKind::Rptr(_lifetime, referent_hir_ty),
) => {
if region.to_region_vid() == needle_fr {
let region_name = renctx.synthesize_region_name();
let region_name = self.synthesize_region_name();
// Just grab the first character, the `&`.
let source_map = self.infcx.tcx.sess.source_map();
......@@ -512,7 +471,6 @@ fn give_name_if_we_can_match_hir_ty(
substs,
needle_fr,
last_segment,
renctx,
search_stack,
) {
return Some(name);
......@@ -557,7 +515,6 @@ fn match_adt_and_segment<'hir>(
substs: SubstsRef<'tcx>,
needle_fr: RegionVid,
last_segment: &'hir hir::PathSegment<'hir>,
renctx: &mut RegionErrorNamingCtx,
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
) -> Option<RegionName> {
// Did the user give explicit arguments? (e.g., `Foo<..>`)
......@@ -569,7 +526,7 @@ fn match_adt_and_segment<'hir>(
| hir::LifetimeName::Error
| hir::LifetimeName::Static
| hir::LifetimeName::Underscore => {
let region_name = renctx.synthesize_region_name();
let region_name = self.synthesize_region_name();
let ampersand_span = lifetime.span;
Some(RegionName {
name: region_name,
......@@ -650,18 +607,14 @@ fn try_match_adt_and_generic_args<'hir>(
/// | let x = Some(&22);
/// - fully elaborated type of `x` is `Option<&'1 u32>`
/// ```
fn give_name_if_anonymous_region_appears_in_upvars(
&self,
fr: RegionVid,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
fn give_name_if_anonymous_region_appears_in_upvars(&self, fr: RegionVid) -> Option<RegionName> {
let upvar_index = self.regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?;
let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
self.infcx.tcx,
&self.upvars,
upvar_index,
);
let region_name = renctx.synthesize_region_name();
let region_name = self.synthesize_region_name();
Some(RegionName {
name: region_name,
......@@ -673,11 +626,7 @@ fn give_name_if_anonymous_region_appears_in_upvars(
/// must be a closure since, in a free fn, such an argument would
/// have to either also appear in an argument (if using elision)
/// or be early bound (named, not in argument).
fn give_name_if_anonymous_region_appears_in_output(
&self,
fr: RegionVid,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option<RegionName> {
let tcx = self.infcx.tcx;
let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
......@@ -687,7 +636,7 @@ fn give_name_if_anonymous_region_appears_in_output(
}
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, renctx.counter);
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0;
let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir");
......@@ -714,7 +663,7 @@ fn give_name_if_anonymous_region_appears_in_output(
// This counter value will already have been used, so this function will increment it
// so the next value will be used next and return the region name that would have been
// used.
name: renctx.synthesize_region_name(),
name: self.synthesize_region_name(),
source: RegionNameSource::AnonRegionFromOutput(
return_span,
mir_description.to_string(),
......@@ -726,7 +675,6 @@ fn give_name_if_anonymous_region_appears_in_output(
fn give_name_if_anonymous_region_appears_in_yield_ty(
&self,
fr: RegionVid,
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
// Note: generators from `async fn` yield `()`, so we don't have to
// worry about them here.
......@@ -740,7 +688,7 @@ fn give_name_if_anonymous_region_appears_in_yield_ty(
}
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, renctx.counter);
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0;
let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir");
......@@ -759,7 +707,7 @@ fn give_name_if_anonymous_region_appears_in_yield_ty(
);
Some(RegionName {
name: renctx.synthesize_region_name(),
name: self.synthesize_region_name(),
source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name),
})
}
......
......@@ -11,7 +11,8 @@
use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind};
use rustc::ty::query::Providers;
use rustc::ty::{self, TyCtxt};
use rustc::ty::{self, RegionVid, TyCtxt};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
......@@ -21,6 +22,7 @@
use rustc_index::vec::IndexVec;
use smallvec::SmallVec;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::mem;
use std::rc::Rc;
......@@ -39,7 +41,7 @@
use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
use crate::transform::MirSource;
use self::diagnostics::AccessKind;
use self::diagnostics::{AccessKind, RegionName};
use self::flows::Flows;
use self::location::LocationTable;
use self::prefixes::PrefixSet;
......@@ -290,6 +292,8 @@ fn do_mir_borrowck<'a, 'tcx>(
dominators,
upvars,
local_names,
region_names: RefCell::default(),
next_region_name: RefCell::new(1),
};
// Compute and report region errors, if any.
......@@ -489,6 +493,13 @@ fn do_mir_borrowck<'a, 'tcx>(
/// Names of local (user) variables (extracted from `var_debug_info`).
local_names: IndexVec<Local, Option<Name>>,
/// Record the region names generated for each region in the given
/// MIR def so that we can reuse them later in help/error messages.
region_names: RefCell<FxHashMap<RegionVid, RegionName>>,
/// The counter for generating new region names.
next_region_name: RefCell<usize>,
}
// Check that:
......
......@@ -1603,23 +1603,6 @@ fn check_member_constraints(
}
}
/// Get the region outlived by `longer_fr` and live at `element`.
crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid {
match element {
RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
RegionElement::RootUniversalRegion(r) => r,
RegionElement::PlaceholderRegion(error_placeholder) => self
.definitions
.iter_enumerated()
.filter_map(|(r, definition)| match definition.origin {
NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
_ => None,
})
.next()
.unwrap(),
}
}
/// We have a constraint `fr1: fr2` that is not satisfied, where
/// `fr2` represents some universal region. Here, `r` is some
/// region where we know that `fr1: r` and this function has the
......
......@@ -87,12 +87,12 @@ error[E0597]: `ap1` does not live long enough
--> $DIR/variadic-ffi-4.rs:24:11
|
LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
| - let's call the lifetime of this reference `'1`
| - let's call the lifetime of this reference `'3`
LL | ap0 = &mut ap1;
| ------^^^^^^^^
| | |
| | borrowed value does not live long enough
| assignment requires that `ap1` is borrowed for `'1`
| assignment requires that `ap1` is borrowed for `'3`
...
LL | }
| - `ap1` dropped here while still borrowed
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册