rcvr_ty_generics.repr(ccx.tcx),
rcvr_ty_predicates.repr(ccx.tcx));
- let tcx = ccx.tcx;
- let mut seen_methods = FnvHashSet();
- for (sig, id, ident, vis, span) in methods {
- if !seen_methods.insert(ident.name) {
- let fn_desc = match sig.explicit_self.node {
- ast::SelfStatic => "associated function",
- _ => "method",
- };
- span_err!(tcx.sess, span, E0201, "duplicate {}", fn_desc);
- }
-
+ for (sig, id, ident, vis, _span) in methods {
convert_method(ccx,
container,
sig,
};
// Convert all the associated consts.
+ // Also, check if there are any duplicate associated items
+ let mut seen_type_items = FnvHashSet();
+ let mut seen_value_items = FnvHashSet();
+
for impl_item in impl_items {
+ let seen_items = match impl_item.node {
+ ast::TypeImplItem(_) => &mut seen_type_items,
+ _ => &mut seen_value_items,
+ };
+ if !seen_items.insert(impl_item.ident.name) {
+ let desc = match impl_item.node {
+ ast::ConstImplItem(_, _) => "associated constant",
+ ast::TypeImplItem(_) => "associated type",
+ ast::MethodImplItem(ref sig, _) =>
+ match sig.explicit_self.node {
+ ast::SelfStatic => "associated function",
+ _ => "method",
+ },
+ _ => "associated item",
+ };
+
+ span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
+ }
+
if let ast::ConstImplItem(ref ty, ref expr) = impl_item.node {
let ty = ccx.icx(&ty_predicates)
.to_ty(&ExplicitRscope, &*ty);
"##,
E0201: r##"
-It is an error to define an associated function more than once.
+It is an error to define two associated items (like methods, associated types,
+associated functions, etc.) with the same identifier.
For example:
impl Foo {
fn bar(&self) -> bool { self.0 > 5 }
-
- // error: duplicate associated function
- fn bar() {}
+ fn bar() {} // error: duplicate associated function
}
trait Baz {
+ type Quux;
fn baz(&self) -> bool;
}
impl Baz for Foo {
+ type Quux = u32;
+
fn baz(&self) -> bool { true }
// error: duplicate method
fn baz(&self) -> bool { self.0 > 5 }
+
+ // error: duplicate associated type
+ type Quux = u32;
}
```
"##,
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_consts)]
+
+struct Foo;
+
+impl Foo {
+ const bar: bool = true;
+ fn bar() {} //~ ERROR duplicate associated function
+}
+
+fn main() {}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// Before the introduction of the "duplicate associated type" error, the
+// program below used to result in the "ambiguous associated type" error E0223,
+// which is unexpected.
+
+trait Foo {
+ type Bar;
+}
+
+struct Baz;
+
+impl Foo for Baz {
+ type Bar = i16;
+ type Bar = u16; //~ ERROR duplicate associated type
+}
+
+fn main() {
+ let x: Baz::Bar = 5;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test for issue #23969
+
+#![feature(associated_consts)]
+
+trait Foo {
+ type Ty;
+ const BAR: u32;
+}
+
+impl Foo for () {
+ type Ty = ();
+ type Ty = usize; //~ ERROR duplicate associated type
+ const BAR: u32 = 7;
+ const BAR: u32 = 8; //~ ERROR duplicate associated constant
+}
+
+fn main() {
+ let _: <() as Foo>::Ty = ();
+ let _: u32 = <() as Foo>::BAR;
+}