Skip to content

Commit f532685

Browse files
committed
Show previous definition of duplicate impl item
1 parent 3dd88f6 commit f532685

File tree

3 files changed

+20
-17
lines changed

3 files changed

+20
-17
lines changed

src/librustc_typeck/coherence/mod.rs

-9
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ use CrateCtxt;
3434
use rustc::infer::{self, InferCtxt, TypeOrigin, new_infer_ctxt};
3535
use std::cell::RefCell;
3636
use std::rc::Rc;
37-
use syntax::ast;
3837
use syntax::codemap::Span;
39-
use syntax::errors::DiagnosticBuilder;
4038
use util::nodemap::{DefIdMap, FnvHashMap};
4139
use rustc::dep_graph::DepNode;
4240
use rustc::hir::map as hir_map;
@@ -517,13 +515,6 @@ fn enforce_trait_manually_implementable(tcx: &TyCtxt, sp: Span, trait_def_id: De
517515
err.emit();
518516
}
519517

520-
// Factored out into helper because the error cannot be defined in multiple locations.
521-
pub fn report_duplicate_item<'tcx>(tcx: &TyCtxt<'tcx>, sp: Span, name: ast::Name)
522-
-> DiagnosticBuilder<'tcx>
523-
{
524-
struct_span_err!(tcx.sess, sp, E0201, "duplicate definitions with name `{}`:", name)
525-
}
526-
527518
pub fn check_coherence(crate_context: &CrateCtxt) {
528519
let _task = crate_context.tcx.dep_graph.in_task(DepNode::Coherence);
529520
let infcx = new_infer_ctxt(crate_context.tcx,

src/librustc_typeck/collect.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ use lint;
6363
use hir::def::Def;
6464
use hir::def_id::DefId;
6565
use constrained_type_params as ctp;
66-
use coherence;
6766
use middle::lang_items::SizedTraitLangItem;
6867
use middle::resolve_lifetime;
6968
use middle::const_val::ConstVal;
@@ -80,13 +79,14 @@ use rscope::*;
8079
use rustc::dep_graph::DepNode;
8180
use rustc::hir::map as hir_map;
8281
use util::common::{ErrorReported, MemoizationMap};
83-
use util::nodemap::{FnvHashMap, FnvHashSet};
82+
use util::nodemap::FnvHashMap;
8483
use write_ty_to_tcx;
8584

8685
use rustc_const_math::ConstInt;
8786

8887
use std::cell::RefCell;
8988
use std::collections::HashSet;
89+
use std::collections::hash_map::Entry::{Occupied, Vacant};
9090
use std::rc::Rc;
9191

9292
use syntax::abi;
@@ -742,16 +742,27 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
742742

743743
// Convert all the associated consts.
744744
// Also, check if there are any duplicate associated items
745-
let mut seen_type_items = FnvHashSet();
746-
let mut seen_value_items = FnvHashSet();
745+
let mut seen_type_items = FnvHashMap();
746+
let mut seen_value_items = FnvHashMap();
747747

748748
for impl_item in impl_items {
749749
let seen_items = match impl_item.node {
750750
hir::ImplItemKind::Type(_) => &mut seen_type_items,
751751
_ => &mut seen_value_items,
752752
};
753-
if !seen_items.insert(impl_item.name) {
754-
coherence::report_duplicate_item(tcx, impl_item.span, impl_item.name).emit();
753+
match seen_items.entry(impl_item.name) {
754+
Occupied(entry) => {
755+
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201,
756+
"duplicate definitions with name `{}`:",
757+
impl_item.name);
758+
span_note!(&mut err, *entry.get(),
759+
"previous definition of `{}` here",
760+
impl_item.name);
761+
err.emit();
762+
}
763+
Vacant(entry) => {
764+
entry.insert(impl_item.span);
765+
}
755766
}
756767

757768
if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {

src/test/compile-fail/impl-duplicate-methods.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
// except according to those terms.
1010

1111
struct Foo;
12+
1213
impl Foo {
13-
fn orange(&self){}
14-
fn orange(&self){} //~ ERROR duplicate definitions
14+
fn orange(&self) {} //~ NOTE previous definition of `orange` here
15+
fn orange(&self) {} //~ ERROR duplicate definitions with name `orange`
1516
}
1617

1718
fn main() {}

0 commit comments

Comments
 (0)