1
Fork 0

Add an optional Span to BrAnon and use it to print better error for HRTB error from generator interior

This commit is contained in:
Jack Huey 2022-10-17 22:08:15 -04:00
parent 1e1e5b8d98
commit 00e314d5ed
23 changed files with 251 additions and 63 deletions

View file

@ -89,10 +89,13 @@ impl<'a> DescriptionCtx<'a> {
};
me.span = Some(sp);
}
ty::BrAnon(idx) => {
ty::BrAnon(idx, span) => {
me.kind = "anon_num_here";
me.num_arg = idx+1;
me.span = Some(tcx.def_span(scope));
me.span = match span {
Some(_) => span,
None => Some(tcx.def_span(scope)),
}
},
_ => {
me.kind = "defined_here_reg";

View file

@ -738,7 +738,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
let var = self.canonical_var(info, r.into());
let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32()) };
let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32(), None) };
let region = ty::ReLateBound(self.binder_index, br);
self.tcx().mk_region(region)
}

View file

@ -206,9 +206,12 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>(
};
(text, sp)
}
ty::BrAnon(idx) => (
ty::BrAnon(idx, span) => (
format!("the anonymous lifetime #{} defined here", idx + 1),
tcx.def_span(scope)
match span {
Some(span) => span,
None => tcx.def_span(scope)
}
),
_ => (
format!("the lifetime `{}` as defined here", region),

View file

@ -10,6 +10,7 @@ pub mod find_anon_type;
mod mismatched_static_lifetime;
mod named_anon_conflict;
mod placeholder_error;
mod placeholder_relation;
mod static_impl_trait;
mod trait_impl_difference;
mod util;
@ -52,7 +53,9 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
// Due to the improved diagnostics returned by the MIR borrow checker, only a subset of
// the nice region errors are required when running under the MIR borrow checker.
self.try_report_named_anon_conflict().or_else(|| self.try_report_placeholder_conflict())
self.try_report_named_anon_conflict()
.or_else(|| self.try_report_placeholder_conflict())
.or_else(|| self.try_report_placeholder_relation())
}
pub fn try_report(&self) -> Option<ErrorGuaranteed> {

View file

@ -68,7 +68,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let is_impl_item = region_info.is_impl_item;
match br {
ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(_) => {}
ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) => {}
_ => {
/* not an anonymous region */
debug!("try_report_named_anon_conflict: not an anonymous region");

View file

@ -0,0 +1,78 @@
use crate::infer::{
error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin,
};
use rustc_data_structures::intern::Interned;
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_middle::ty::{self, RePlaceholder, Region};
impl<'tcx> NiceRegionError<'_, 'tcx> {
/// Emitted wwhen given a `ConcreteFailure` when relating two placeholders.
pub(super) fn try_report_placeholder_relation(
&self,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
match &self.error {
Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::RelateRegionParamBound(span),
Region(Interned(RePlaceholder(ty::Placeholder { name: sub_name, .. }), _)),
Region(Interned(RePlaceholder(ty::Placeholder { name: sup_name, .. }), _)),
)) => {
let msg = "lifetime bound not satisfied";
let mut err = self.tcx().sess.struct_span_err(*span, msg);
let (sub_span, sub_symbol) = match sub_name {
ty::BrNamed(def_id, symbol) => {
(Some(self.tcx().def_span(def_id)), Some(symbol))
}
ty::BrAnon(_, span) => (*span, None),
ty::BrEnv => (None, None),
};
let (sup_span, sup_symbol) = match sup_name {
ty::BrNamed(def_id, symbol) => {
(Some(self.tcx().def_span(def_id)), Some(symbol))
}
ty::BrAnon(_, span) => (*span, None),
ty::BrEnv => (None, None),
};
match (sub_span, sup_span, sub_symbol, sup_symbol) {
(Some(sub_span), Some(sup_span), Some(sub_symbol), Some(sup_symbol)) => {
err.span_note(
sub_span,
format!("the lifetime `{sub_symbol}` defined here..."),
);
err.span_note(
sup_span,
format!("...must outlive the lifetime `{sup_symbol}` defined here"),
);
}
(Some(sub_span), Some(sup_span), _, Some(sup_symbol)) => {
err.span_note(sub_span, format!("the lifetime defined here..."));
err.span_note(
sup_span,
format!("...must outlive the lifetime `{sup_symbol}` defined here"),
);
}
(Some(sub_span), Some(sup_span), Some(sub_symbol), _) => {
err.span_note(
sub_span,
format!("the lifetime `{sub_symbol}` defined here..."),
);
err.span_note(
sup_span,
format!("...must outlive the lifetime defined here"),
);
}
(Some(sub_span), Some(sup_span), _, _) => {
err.span_note(sub_span, format!("the lifetime defined here, ..."));
err.span_note(
sup_span,
format!("...must outlive the lifetime defined here"),
);
}
_ => {}
}
Some(err)
}
_ => None,
}
}
}