use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
-use rustc_middle::ty::error::ExpectedFound;
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::print::RegionHighlightMode;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor};
+
use rustc_span::{MultiSpan, Span, Symbol};
+use std::ops::ControlFlow;
+
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option<ErrorReported> {
{
if let SubregionOrigin::CompareImplTypeObligation {
span,
- item_name,
impl_item_def_id,
trait_item_def_id,
} = origin
{
- self.emit_associated_type_err(span, item_name, impl_item_def_id, trait_item_def_id);
+ self.emit_associated_type_err(
+ span,
+ self.infcx.tcx.item_name(impl_item_def_id),
+ impl_item_def_id,
+ trait_item_def_id,
+ );
return Some(ErrorReported);
}
}
.tcx()
.sess
.struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature");
+
+ // Mark all unnamed regions in the type with a number.
+ // This diagnostic is called in response to lifetime errors, so be informative.
+ struct HighlightBuilder<'tcx> {
+ highlight: RegionHighlightMode,
+ tcx: TyCtxt<'tcx>,
+ counter: usize,
+ }
+
+ impl HighlightBuilder<'tcx> {
+ fn build(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> RegionHighlightMode {
+ let mut builder =
+ HighlightBuilder { highlight: RegionHighlightMode::default(), counter: 1, tcx };
+ builder.visit_ty(ty);
+ builder.highlight
+ }
+ }
+
+ impl<'tcx> ty::fold::TypeVisitor<'tcx> for HighlightBuilder<'tcx> {
+ fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
+ Some(self.tcx)
+ }
+
+ fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
+ if !r.has_name() && self.counter <= 3 {
+ self.highlight.highlighting_region(r, self.counter);
+ self.counter += 1;
+ }
+ r.super_visit_with(self)
+ }
+ }
+
+ let expected_highlight = HighlightBuilder::build(self.tcx(), expected);
+ let expected = self
+ .infcx
+ .extract_inference_diagnostics_data(expected.into(), Some(expected_highlight))
+ .name;
+ let found_highlight = HighlightBuilder::build(self.tcx(), found);
+ let found =
+ self.infcx.extract_inference_diagnostics_data(found.into(), Some(found_highlight)).name;
+
err.span_label(sp, &format!("found `{}`", found));
err.span_label(trait_sp, &format!("expected `{}`", expected));
);
}
- if let Some((expected, found)) =
- self.infcx.expected_found_str_ty(ExpectedFound { expected, found })
- {
- // Highlighted the differences when showing the "expected/found" note.
- err.note_expected_found(&"", expected, &"", found);
- } else {
- // This fallback shouldn't be necessary, but let's keep it in just in case.
- err.note(&format!("expected `{}`\n found `{}`", expected, found));
- }
+ err.note(&format!("expected `{}`\n found `{}`", expected, found));
+
err.span_help(
type_param_span,
"the lifetime requirements from the `impl` do not correspond to the requirements in \