]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/coherence/inherent_impls_overlap.rs
New upstream version 1.40.0+dfsg1
[rustc.git] / src / librustc_typeck / coherence / inherent_impls_overlap.rs
CommitLineData
9fa01778 1use crate::namespace::Namespace;
cc61c64b
XL
2use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
3use rustc::hir;
4use rustc::hir::itemlikevisit::ItemLikeVisitor;
ff7c6d11 5use rustc::traits::{self, IntercrateMode};
abe05a73 6use rustc::ty::TyCtxt;
cc61c64b 7
416331ca 8pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) {
cc61c64b 9 assert_eq!(crate_num, LOCAL_CRATE);
0731742a 10 let krate = tcx.hir().krate();
cc61c64b
XL
11 krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx });
12}
13
dc9dc135
XL
14struct InherentOverlapChecker<'tcx> {
15 tcx: TyCtxt<'tcx>,
cc61c64b
XL
16}
17
dc9dc135 18impl InherentOverlapChecker<'tcx> {
ea8adc8c 19 fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId,
48663c56 20 overlap: traits::OverlapResult<'_>) {
cc61c64b
XL
21
22 let name_and_namespace = |def_id| {
23 let item = self.tcx.associated_item(def_id);
532ac7d7 24 (item.ident.modern(), Namespace::from(item.kind))
cc61c64b
XL
25 };
26
27 let impl_items1 = self.tcx.associated_item_def_ids(impl1);
28 let impl_items2 = self.tcx.associated_item_def_ids(impl2);
29
30 for &item1 in &impl_items1[..] {
31 let (name, namespace) = name_and_namespace(item1);
32
33 for &item2 in &impl_items2[..] {
34 if (name, namespace) == name_and_namespace(item2) {
48663c56 35 let mut err =
ff7c6d11
XL
36 struct_span_err!(self.tcx.sess,
37 self.tcx.span_of_impl(item1).unwrap(),
38 E0592,
39 "duplicate definitions with name `{}`",
48663c56 40 name);
ea8adc8c
XL
41 err.span_label(self.tcx.span_of_impl(item1).unwrap(),
42 format!("duplicate definitions for `{}`", name));
43 err.span_label(self.tcx.span_of_impl(item2).unwrap(),
44 format!("other definition for `{}`", name));
45
46 for cause in &overlap.intercrate_ambiguity_causes {
47 cause.add_intercrate_ambiguity_hint(&mut err);
48 }
49
0731742a
XL
50 if overlap.involves_placeholder {
51 traits::add_placeholder_note(&mut err);
52 }
53
ea8adc8c 54 err.emit();
cc61c64b
XL
55 }
56 }
57 }
58 }
59
60 fn check_for_overlapping_inherent_impls(&self, ty_def_id: DefId) {
7cac9316 61 let impls = self.tcx.inherent_impls(ty_def_id);
cc61c64b
XL
62
63 for (i, &impl1_def_id) in impls.iter().enumerate() {
64 for &impl2_def_id in &impls[(i + 1)..] {
48663c56 65 traits::overlapping_impls(
ff7c6d11
XL
66 self.tcx,
67 impl1_def_id,
68 impl2_def_id,
69 IntercrateMode::Issue43355,
70 |overlap| {
71 self.check_for_common_items_in_impls(
72 impl1_def_id,
73 impl2_def_id,
74 overlap,
ff7c6d11
XL
75 );
76 false
77 },
78 || true,
79 );
cc61c64b
XL
80 }
81 }
82 }
83}
84
dc9dc135 85impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
cc61c64b 86 fn visit_item(&mut self, item: &'v hir::Item) {
e74abb32 87 match item.kind {
8faf50e0
XL
88 hir::ItemKind::Enum(..) |
89 hir::ItemKind::Struct(..) |
90 hir::ItemKind::Trait(..) |
91 hir::ItemKind::Union(..) => {
416331ca 92 let type_def_id = self.tcx.hir().local_def_id(item.hir_id);
cc61c64b
XL
93 self.check_for_overlapping_inherent_impls(type_def_id);
94 }
95 _ => {}
96 }
97 }
98
99 fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
100 }
101
102 fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
103 }
104}