1
Fork 0

Refactor compare_method

Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
This commit is contained in:
varkor 2019-02-20 01:16:52 +00:00
parent f7cd97f786
commit a8361eb6fa

View file

@ -6,7 +6,7 @@ use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
use rustc::ty::error::{ExpectedFound, TypeError};
use rustc::ty::subst::{Subst, InternalSubsts, SubstsRef};
use rustc::util::common::ErrorReported;
use errors::Applicability;
use errors::{Applicability, DiagnosticId};
use syntax_pos::Span;
@ -576,55 +576,78 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Ok(())
}
fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_m: &ty::AssociatedItem,
impl_m_span: Span,
trait_m: &ty::AssociatedItem,
trait_item_span: Option<Span>)
-> Result<(), ErrorReported> {
let impl_m_generics = tcx.generics_of(impl_m.def_id);
let trait_m_generics = tcx.generics_of(trait_m.def_id);
let num_impl_m_type_params = impl_m_generics.own_counts().types;
let num_trait_m_type_params = trait_m_generics.own_counts().types;
fn compare_number_of_generics<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_: &ty::AssociatedItem,
impl_span: Span,
trait_: &ty::AssociatedItem,
trait_span: Option<Span>,
) -> Result<(), ErrorReported> {
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
if num_impl_m_type_params != num_trait_m_type_params {
let impl_m_node_id = tcx.hir().as_local_node_id(impl_m.def_id).unwrap();
let impl_m_item = tcx.hir().expect_impl_item(impl_m_node_id);
let span = if impl_m_item.generics.params.is_empty()
|| impl_m_item.generics.span.is_dummy() // impl Trait in argument position (#55374)
{
impl_m_span
let matchings = [
("type", trait_own_counts.types, impl_own_counts.types),
("const", trait_own_counts.consts, impl_own_counts.consts),
];
let mut err_occurred = false;
for &(kind, trait_count, impl_count) in &matchings {
if impl_count != trait_count {
err_occurred = true;
let impl_node_id = tcx.hir().as_local_node_id(impl_.def_id).unwrap();
let impl_item = tcx.hir().expect_impl_item(impl_node_id);
let span = if impl_item.generics.params.is_empty()
|| impl_item.generics.span.is_dummy() { // argument position impl Trait (#55374)
impl_span
} else {
impl_m_item.generics.span
impl_item.generics.span
};
let mut err = struct_span_err!(tcx.sess, span, E0049,
"method `{}` has {} but its trait declaration has {}",
trait_m.ident,
potentially_plural_count(num_impl_m_type_params, "type parameter"),
potentially_plural_count(num_trait_m_type_params, "type parameter")
let mut err = tcx.sess.struct_span_err_with_code(
span,
&format!(
"method `{}` has {} {kind} parameter{} but its trait \
declaration has {} {kind} parameter{}",
trait_.ident,
impl_count,
if impl_count != 1 { "s" } else { "" },
trait_count,
if trait_count != 1 { "s" } else { "" },
kind = kind,
),
DiagnosticId::Error("E0049".into()),
);
let mut suffix = None;
if let Some(span) = trait_item_span {
err.span_label(span, format!("expected {}",
potentially_plural_count(num_trait_m_type_params, "type parameter")));
if let Some(span) = trait_span {
err.span_label(
span,
format!("expected {} {} parameter{}", trait_count, kind,
if trait_count != 1 { "s" } else { "" })
);
} else {
suffix = Some(format!(", expected {}", num_trait_m_type_params));
suffix = Some(format!(", expected {}", trait_count));
}
err.span_label(span,
format!("found {}{}",
potentially_plural_count(num_impl_m_type_params, "type parameter"),
suffix.as_ref().map(|s| &s[..]).unwrap_or("")));
err.span_label(
span,
format!("found {} {} parameter{}{}", impl_count, kind,
if impl_count != 1 { "s" } else { "" },
suffix.unwrap_or_else(|| String::new())),
);
err.emit();
return Err(ErrorReported);
}
}
if err_occurred {
Err(ErrorReported)
} else {
Ok(())
}
}
fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@ -725,12 +748,12 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let trait_m_generics = tcx.generics_of(trait_m.def_id);
let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind {
GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
GenericParamDefKind::Lifetime => None,
GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
});
let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
match param.kind {
GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
GenericParamDefKind::Lifetime => None,
GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
}
});
for ((impl_def_id, impl_synthetic), (trait_def_id, trait_synthetic))