Skip to content

Commit 7ac997d

Browse files
author
Nick Hamann
committed
Detect duplicate implementations of assoc. types and constants.
Adds error codes E0398 and E0399. Fixes rust-lang#23969.
1 parent e8af475 commit 7ac997d

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

src/librustc_typeck/collect.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,14 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
856856
};
857857

858858
// Convert all the associated consts.
859+
let mut seen_consts = FnvHashSet();
859860
for impl_item in impl_items {
860861
if let ast::ConstImplItem(ref ty, ref expr) = impl_item.node {
862+
if !seen_consts.insert(impl_item.ident.name) {
863+
span_err!(tcx.sess, impl_item.span, E0398,
864+
"duplicate associated constant");
865+
}
866+
861867
let ty = ccx.icx(&ty_predicates)
862868
.to_ty(&ExplicitRscope, &*ty);
863869
tcx.tcache.borrow_mut().insert(local_def(impl_item.id),
@@ -873,8 +879,13 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
873879
}
874880

875881
// Convert all the associated types.
882+
let mut seen_types = FnvHashSet();
876883
for impl_item in impl_items {
877884
if let ast::TypeImplItem(ref ty) = impl_item.node {
885+
if !seen_types.insert(impl_item.ident.name) {
886+
span_err!(tcx.sess, impl_item.span, E0399,
887+
"duplicate associated type");
888+
}
878889
if opt_trait_ref.is_none() {
879890
span_err!(tcx.sess, impl_item.span, E0202,
880891
"associated types are not allowed in inherent impls");

src/librustc_typeck/diagnostics.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,8 @@ register_diagnostics! {
12841284
// `#[lang = \"{}\"]` is allowed for the `{}` primitive
12851285
E0391, // unsupported cyclic reference between types/traits detected
12861286
E0392, // parameter `{}` is never used
1287-
E0393 // the type parameter `{}` must be explicitly specified in an object
1287+
E0393, // the type parameter `{}` must be explicitly specified in an object
12881288
// type because its default value `{}` references the type `Self`"
1289+
E0398, // duplicate associated constant
1290+
E0399 // duplicate associated type
12891291
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2015 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+
// Before the introduction of the "duplicate associated type" error, the
12+
// program below used to result in the "ambiguous associated type" error E0223,
13+
// which is unexpected.
14+
15+
trait Foo {
16+
type Bar;
17+
}
18+
19+
struct Baz;
20+
21+
impl Foo for Baz {
22+
type Bar = i16;
23+
type Bar = u16; //~ ERROR duplicate associated type
24+
}
25+
26+
fn main() {
27+
let x: Baz::Bar = 5;
28+
}

src/test/compile-fail/issue-23969.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2015 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+
#![feature(associated_consts)]
12+
13+
trait Foo {
14+
type Ty;
15+
const BAR: u32;
16+
}
17+
18+
impl Foo for () {
19+
type Ty = ();
20+
type Ty = usize; //~ ERROR duplicate associated type
21+
const BAR: u32 = 7;
22+
const BAR: u32 = 8; //~ ERROR duplicate associated constant
23+
}
24+
25+
fn main() {
26+
let _: <() as Foo>::Ty = ();
27+
let _: u32 = <() as Foo>::BAR;
28+
}

0 commit comments

Comments
 (0)