Skip to content

Commit 4df5288

Browse files
committed
move duplicate checking into TypeCheck
This completes the effort to not touch the impl-items during `Collect(Impl)`.
1 parent 29a39ab commit 4df5288

File tree

3 files changed

+54
-31
lines changed

3 files changed

+54
-31
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use rustc::hir;
12+
use rustc_data_structures::fx::FxHashMap;
13+
use std::collections::hash_map::Entry::{Occupied, Vacant};
14+
15+
use CrateCtxt;
16+
17+
/// Enforce that we do not have two items in an impl with the same name.
18+
pub fn enforce_impl_items_are_distinct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
19+
impl_item_ids: &[hir::ImplItemId])
20+
{
21+
let tcx = ccx.tcx;
22+
let mut seen_type_items = FxHashMap();
23+
let mut seen_value_items = FxHashMap();
24+
for &impl_item_id in impl_item_ids {
25+
let impl_item = tcx.map.impl_item(impl_item_id);
26+
let seen_items = match impl_item.node {
27+
hir::ImplItemKind::Type(_) => &mut seen_type_items,
28+
_ => &mut seen_value_items,
29+
};
30+
match seen_items.entry(impl_item.name) {
31+
Occupied(entry) => {
32+
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201,
33+
"duplicate definitions with name `{}`:",
34+
impl_item.name);
35+
err.span_label(*entry.get(),
36+
&format!("previous definition of `{}` here",
37+
impl_item.name));
38+
err.span_label(impl_item.span, &format!("duplicate definition"));
39+
err.emit();
40+
}
41+
Vacant(entry) => {
42+
entry.insert(impl_item.span);
43+
}
44+
}
45+
}
46+
}

src/librustc_typeck/check/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ mod closure;
143143
mod callee;
144144
mod compare_method;
145145
mod intrinsic;
146+
mod impl_item_duplicate;
146147
mod impl_parameters_used;
147148
mod op;
148149

@@ -834,6 +835,8 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
834835
impl_def_id,
835836
impl_item_ids);
836837

838+
impl_item_duplicate::enforce_impl_items_are_distinct(ccx,
839+
impl_item_ids);
837840
}
838841
hir::ItemTrait(..) => {
839842
let def_id = ccx.tcx.map.local_def_id(it.id);

src/librustc_typeck/collect.rs

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ use CrateCtxt;
7777
use rustc_const_math::ConstInt;
7878

7979
use std::cell::RefCell;
80-
use std::collections::hash_map::Entry::{Occupied, Vacant};
8180

8281
use syntax::{abi, ast, attr};
8382
use syntax::parse::token::{self, keywords};
@@ -732,7 +731,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
732731
ref generics,
733732
ref opt_trait_ref,
734733
ref selfty,
735-
ref impl_item_ids) => {
734+
ref _impl_item_ids /* [1] */) => {
735+
// [1]: We really don't want to be inspecting the details
736+
// of impl-items here; it creates bad edges in the
737+
// incr. comp. graph.
738+
736739
// Create generics from the generics specified in the impl head.
737740
debug!("convert: ast_generics={:?}", generics);
738741
let def_id = ccx.tcx.map.local_def_id(it.id);
@@ -763,35 +766,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
763766
&mut ctp::parameters_for_impl(selfty, trait_ref));
764767

765768
tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
766-
767-
768-
// Convert all the associated consts.
769-
// Also, check if there are any duplicate associated items
770-
let mut seen_type_items = FxHashMap();
771-
let mut seen_value_items = FxHashMap();
772-
773-
for &impl_item_id in impl_item_ids {
774-
let impl_item = tcx.map.impl_item(impl_item_id);
775-
let seen_items = match impl_item.node {
776-
hir::ImplItemKind::Type(_) => &mut seen_type_items,
777-
_ => &mut seen_value_items,
778-
};
779-
match seen_items.entry(impl_item.name) {
780-
Occupied(entry) => {
781-
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201,
782-
"duplicate definitions with name `{}`:",
783-
impl_item.name);
784-
err.span_label(*entry.get(),
785-
&format!("previous definition of `{}` here",
786-
impl_item.name));
787-
err.span_label(impl_item.span, &format!("duplicate definition"));
788-
err.emit();
789-
}
790-
Vacant(entry) => {
791-
entry.insert(impl_item.span);
792-
}
793-
}
794-
}
795769
},
796770
hir::ItemTrait(.., ref trait_items) => {
797771
let trait_def = trait_def_of_item(ccx, it);

0 commit comments

Comments
 (0)