1 use crate::namespace
::Namespace
;
2 use rustc
::hir
::def_id
::{CrateNum, DefId, LOCAL_CRATE}
;
4 use rustc
::hir
::itemlikevisit
::ItemLikeVisitor
;
5 use rustc
::traits
::{self, IntercrateMode}
;
8 use rustc_error_codes
::*;
10 pub fn crate_inherent_impls_overlap_check(tcx
: TyCtxt
<'_
>, crate_num
: CrateNum
) {
11 assert_eq
!(crate_num
, LOCAL_CRATE
);
12 let krate
= tcx
.hir().krate();
13 krate
.visit_all_item_likes(&mut InherentOverlapChecker { tcx }
);
16 struct InherentOverlapChecker
<'tcx
> {
20 impl InherentOverlapChecker
<'tcx
> {
21 fn check_for_common_items_in_impls(&self, impl1
: DefId
, impl2
: DefId
,
22 overlap
: traits
::OverlapResult
<'_
>) {
24 let name_and_namespace
= |def_id
| {
25 let item
= self.tcx
.associated_item(def_id
);
26 (item
.ident
.modern(), Namespace
::from(item
.kind
))
29 let impl_items1
= self.tcx
.associated_item_def_ids(impl1
);
30 let impl_items2
= self.tcx
.associated_item_def_ids(impl2
);
32 for &item1
in &impl_items1
[..] {
33 let (name
, namespace
) = name_and_namespace(item1
);
35 for &item2
in &impl_items2
[..] {
36 if (name
, namespace
) == name_and_namespace(item2
) {
38 struct_span_err
!(self.tcx
.sess
,
39 self.tcx
.span_of_impl(item1
).unwrap(),
41 "duplicate definitions with name `{}`",
43 err
.span_label(self.tcx
.span_of_impl(item1
).unwrap(),
44 format
!("duplicate definitions for `{}`", name
));
45 err
.span_label(self.tcx
.span_of_impl(item2
).unwrap(),
46 format
!("other definition for `{}`", name
));
48 for cause
in &overlap
.intercrate_ambiguity_causes
{
49 cause
.add_intercrate_ambiguity_hint(&mut err
);
52 if overlap
.involves_placeholder
{
53 traits
::add_placeholder_note(&mut err
);
62 fn check_for_overlapping_inherent_impls(&self, ty_def_id
: DefId
) {
63 let impls
= self.tcx
.inherent_impls(ty_def_id
);
65 for (i
, &impl1_def_id
) in impls
.iter().enumerate() {
66 for &impl2_def_id
in &impls
[(i
+ 1)..] {
67 traits
::overlapping_impls(
71 IntercrateMode
::Issue43355
,
73 self.check_for_common_items_in_impls(
87 impl ItemLikeVisitor
<'v
> for InherentOverlapChecker
<'tcx
> {
88 fn visit_item(&mut self, item
: &'v hir
::Item
) {
90 hir
::ItemKind
::Enum(..) |
91 hir
::ItemKind
::Struct(..) |
92 hir
::ItemKind
::Trait(..) |
93 hir
::ItemKind
::Union(..) => {
94 let type_def_id
= self.tcx
.hir().local_def_id(item
.hir_id
);
95 self.check_for_overlapping_inherent_impls(type_def_id
);
101 fn visit_trait_item(&mut self, _trait_item
: &hir
::TraitItem
) {
104 fn visit_impl_item(&mut self, _impl_item
: &hir
::ImplItem
) {