blob: 695f3e47fb5d7b18643b6b2e85bb4c903fc1ccb2 [file] [log] [blame]
//! Error Reporting for `impl` items that do not match the obligations from their `trait`.
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::{Subtype, ValuePairs};
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
use rustc_errors::ErrorReported;
use rustc_middle::ty::Ty;
use rustc_span::Span;
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 Some(ref error) = self.error {
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
if let RegionResolutionError::SubSupConflict(
_,
var_origin,
sub_origin,
_sub,
sup_origin,
_sup,
) = error.clone()
{
if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) =
(&sup_origin, &sub_origin)
{
if let (
ValuePairs::Types(sub_expected_found),
ValuePairs::Types(sup_expected_found),
CompareImplMethodObligation { trait_item_def_id, .. },
) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code)
{
if sup_expected_found == sub_expected_found {
self.emit_err(
var_origin.span(),
sub_expected_found.expected,
sub_expected_found.found,
self.tcx().def_span(*trait_item_def_id),
);
return Some(ErrorReported);
}
}
}
}
}
None
}
fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Span) {
let mut err = self
.tcx()
.sess
.struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature");
err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found));
err.span_label(sp, &format!("found {:?}", found));
err.span_label(impl_sp, &format!("expected {:?}", expected));
err.emit();
}
}