Skip to content

Commit a8361eb

Browse files
varkoryodaldevoid
andcommitted
Refactor compare_method
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
1 parent f7cd97f commit a8361eb

File tree

1 file changed

+68
-45
lines changed

1 file changed

+68
-45
lines changed

src/librustc_typeck/check/compare_method.rs

Lines changed: 68 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
66
use rustc::ty::error::{ExpectedFound, TypeError};
77
use rustc::ty::subst::{Subst, InternalSubsts, SubstsRef};
88
use rustc::util::common::ErrorReported;
9-
use errors::Applicability;
9+
use errors::{Applicability, DiagnosticId};
1010

1111
use syntax_pos::Span;
1212

@@ -576,55 +576,78 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
576576
Ok(())
577577
}
578578

579-
fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
580-
impl_m: &ty::AssociatedItem,
581-
impl_m_span: Span,
582-
trait_m: &ty::AssociatedItem,
583-
trait_item_span: Option<Span>)
584-
-> Result<(), ErrorReported> {
585-
let impl_m_generics = tcx.generics_of(impl_m.def_id);
586-
let trait_m_generics = tcx.generics_of(trait_m.def_id);
587-
let num_impl_m_type_params = impl_m_generics.own_counts().types;
588-
let num_trait_m_type_params = trait_m_generics.own_counts().types;
589-
590-
if num_impl_m_type_params != num_trait_m_type_params {
591-
let impl_m_node_id = tcx.hir().as_local_node_id(impl_m.def_id).unwrap();
592-
let impl_m_item = tcx.hir().expect_impl_item(impl_m_node_id);
593-
let span = if impl_m_item.generics.params.is_empty()
594-
|| impl_m_item.generics.span.is_dummy() // impl Trait in argument position (#55374)
595-
{
596-
impl_m_span
597-
} else {
598-
impl_m_item.generics.span
599-
};
579+
fn compare_number_of_generics<'a, 'tcx>(
580+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
581+
impl_: &ty::AssociatedItem,
582+
impl_span: Span,
583+
trait_: &ty::AssociatedItem,
584+
trait_span: Option<Span>,
585+
) -> Result<(), ErrorReported> {
586+
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
587+
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
588+
589+
let matchings = [
590+
("type", trait_own_counts.types, impl_own_counts.types),
591+
("const", trait_own_counts.consts, impl_own_counts.consts),
592+
];
593+
594+
let mut err_occurred = false;
595+
for &(kind, trait_count, impl_count) in &matchings {
596+
if impl_count != trait_count {
597+
err_occurred = true;
598+
599+
let impl_node_id = tcx.hir().as_local_node_id(impl_.def_id).unwrap();
600+
let impl_item = tcx.hir().expect_impl_item(impl_node_id);
601+
let span = if impl_item.generics.params.is_empty()
602+
|| impl_item.generics.span.is_dummy() { // argument position impl Trait (#55374)
603+
impl_span
604+
} else {
605+
impl_item.generics.span
606+
};
600607

601-
let mut err = struct_span_err!(tcx.sess, span, E0049,
602-
"method `{}` has {} but its trait declaration has {}",
603-
trait_m.ident,
604-
potentially_plural_count(num_impl_m_type_params, "type parameter"),
605-
potentially_plural_count(num_trait_m_type_params, "type parameter")
606-
);
608+
let mut err = tcx.sess.struct_span_err_with_code(
609+
span,
610+
&format!(
611+
"method `{}` has {} {kind} parameter{} but its trait \
612+
declaration has {} {kind} parameter{}",
613+
trait_.ident,
614+
impl_count,
615+
if impl_count != 1 { "s" } else { "" },
616+
trait_count,
617+
if trait_count != 1 { "s" } else { "" },
618+
kind = kind,
619+
),
620+
DiagnosticId::Error("E0049".into()),
621+
);
607622

608-
let mut suffix = None;
623+
let mut suffix = None;
609624

610-
if let Some(span) = trait_item_span {
611-
err.span_label(span, format!("expected {}",
612-
potentially_plural_count(num_trait_m_type_params, "type parameter")));
613-
} else {
614-
suffix = Some(format!(", expected {}", num_trait_m_type_params));
615-
}
616-
617-
err.span_label(span,
618-
format!("found {}{}",
619-
potentially_plural_count(num_impl_m_type_params, "type parameter"),
620-
suffix.as_ref().map(|s| &s[..]).unwrap_or("")));
625+
if let Some(span) = trait_span {
626+
err.span_label(
627+
span,
628+
format!("expected {} {} parameter{}", trait_count, kind,
629+
if trait_count != 1 { "s" } else { "" })
630+
);
631+
} else {
632+
suffix = Some(format!(", expected {}", trait_count));
633+
}
621634

622-
err.emit();
635+
err.span_label(
636+
span,
637+
format!("found {} {} parameter{}{}", impl_count, kind,
638+
if impl_count != 1 { "s" } else { "" },
639+
suffix.unwrap_or_else(|| String::new())),
640+
);
623641

624-
return Err(ErrorReported);
642+
err.emit();
643+
}
625644
}
626645

627-
Ok(())
646+
if err_occurred {
647+
Err(ErrorReported)
648+
} else {
649+
Ok(())
650+
}
628651
}
629652

630653
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>,
725748
let trait_m_generics = tcx.generics_of(trait_m.def_id);
726749
let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind {
727750
GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
728-
GenericParamDefKind::Lifetime => None,
751+
GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
729752
});
730753
let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
731754
match param.kind {
732755
GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
733-
GenericParamDefKind::Lifetime => None,
756+
GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
734757
}
735758
});
736759
for ((impl_def_id, impl_synthetic), (trait_def_id, trait_synthetic))

0 commit comments

Comments
 (0)