Provide more information for HRTB lifetime errors involving closures
This commit is contained in:
parent
704e47f78b
commit
a8a974245e
18 changed files with 392 additions and 25 deletions
|
@ -98,7 +98,7 @@ pub(super) fn note_and_explain_region(
|
|||
// uh oh, hope no user ever sees THIS
|
||||
ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), None),
|
||||
|
||||
ty::RePlaceholder(_) => ("any other region".to_string(), None),
|
||||
ty::RePlaceholder(_) => return,
|
||||
|
||||
// FIXME(#13998) RePlaceholder should probably print like
|
||||
// ReFree rather than dumping Debug output on the user.
|
||||
|
@ -1675,6 +1675,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
self.check_and_note_conflicting_crates(diag, terr);
|
||||
self.tcx.note_and_explain_type_err(diag, terr, cause, span, body_owner_def_id.to_def_id());
|
||||
|
||||
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values {
|
||||
if let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() {
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
let span = self.tcx.hir().span(hir_id);
|
||||
diag.span_note(span, "this closure does not fulfill the lifetime requirements");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It reads better to have the error origin as the final
|
||||
// thing.
|
||||
self.note_error_origin(diag, cause, exp_found);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
|
||||
use crate::infer::{self, InferCtxt, SubregionOrigin};
|
||||
use rustc_errors::{struct_span_err, DiagnosticBuilder};
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::{self, Region};
|
||||
|
||||
|
@ -107,14 +108,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
infer::Subtype(box trace) => {
|
||||
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
|
||||
let mut err = self.report_and_explain_type_error(trace, &terr);
|
||||
note_and_explain_region(self.tcx, &mut err, "", sup, "...");
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
&mut err,
|
||||
"...does not necessarily outlive ",
|
||||
sub,
|
||||
"",
|
||||
);
|
||||
match (sub, sup) {
|
||||
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
|
||||
(ty::RePlaceholder(_), _) => {
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
&mut err,
|
||||
"",
|
||||
sup,
|
||||
" doesn't meet the lifetime requirements",
|
||||
);
|
||||
}
|
||||
(_, ty::RePlaceholder(_)) => {
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
&mut err,
|
||||
"the required lifetime does not necessarily outlive ",
|
||||
sub,
|
||||
"",
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
note_and_explain_region(self.tcx, &mut err, "", sup, "...");
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
&mut err,
|
||||
"...does not necessarily outlive ",
|
||||
sub,
|
||||
"",
|
||||
);
|
||||
}
|
||||
}
|
||||
err
|
||||
}
|
||||
infer::Reborrow(span) => {
|
||||
|
@ -286,13 +310,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
sup: Region<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
// I can't think how to do better than this right now. -nikomatsakis
|
||||
debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
|
||||
match placeholder_origin {
|
||||
infer::Subtype(box ref trace)
|
||||
if matches!(
|
||||
&trace.cause.code.peel_derives(),
|
||||
ObligationCauseCode::BindingObligation(..)
|
||||
) =>
|
||||
{
|
||||
// Hack to get around the borrow checker because trace.cause has an `Rc`.
|
||||
if let ObligationCauseCode::BindingObligation(_, span) =
|
||||
&trace.cause.code.peel_derives()
|
||||
{
|
||||
let span = *span;
|
||||
let mut err = self.report_concrete_failure(placeholder_origin, sub, sup);
|
||||
err.span_note(span, "the lifetime requirement is introduced here");
|
||||
err
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
infer::Subtype(box trace) => {
|
||||
let terr = TypeError::RegionsPlaceholderMismatch;
|
||||
self.report_and_explain_type_error(trace, &terr)
|
||||
return self.report_and_explain_type_error(trace, &terr);
|
||||
}
|
||||
|
||||
_ => self.report_concrete_failure(placeholder_origin, sub, sup),
|
||||
_ => return self.report_concrete_failure(placeholder_origin, sub, sup),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue