about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2015-07-17 19:06:23 +0530
committerManish Goregaokar <manishsmail@gmail.com>2015-07-17 19:06:23 +0530
commitef9b9cebe3d433cbe24ff392d1c621802b7286be (patch)
tree2d96d36775aab2bec40a60fe1d4ad81cdf5ac449 /src
parent8e9bd6cd26a8f9d11188e39c52aafb4436b09990 (diff)
parent560bb0af6d0dda06b856a80cc5095b7d552b8406 (diff)
downloadrust-ef9b9cebe3d433cbe24ff392d1c621802b7286be.tar.gz
rust-ef9b9cebe3d433cbe24ff392d1c621802b7286be.zip
Rollup merge of #25993 - nham:fix_23969, r=nikomatsakis
Adds two error codes, one for duplicate associated constants and one for types. I'm not certain these should each have their own code, but E0201 is already solely for duplicate associated functions so at least it kinda matches. This will lead to somewhat redundant error explanations, but that's nothing new!

Fixes #23969.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/collect.rs35
-rw-r--r--src/librustc_typeck/diagnostics.rs13
-rw-r--r--src/test/compile-fail/associated-item-duplicate-names-2.rs20
-rw-r--r--src/test/compile-fail/associated-item-duplicate-names-3.rs28
-rw-r--r--src/test/compile-fail/associated-item-duplicate-names.rs30
5 files changed, 111 insertions, 15 deletions
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 8949edb027e..5a6519cb4b7 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -747,17 +747,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
            rcvr_ty_generics,
            rcvr_ty_predicates);
 
-    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,
@@ -859,7 +849,30 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
             };
 
             // 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);
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 2069e3098e6..ed04fde463c 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -1689,7 +1689,8 @@ unsafe impl Bar for Foo { }
 "##,
 
 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:
 
@@ -1698,20 +1699,24 @@ struct Foo(u8);
 
 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;
 }
 ```
 "##,
diff --git a/src/test/compile-fail/associated-item-duplicate-names-2.rs b/src/test/compile-fail/associated-item-duplicate-names-2.rs
new file mode 100644
index 00000000000..6a7eaecae7f
--- /dev/null
+++ b/src/test/compile-fail/associated-item-duplicate-names-2.rs
@@ -0,0 +1,20 @@
+// 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() {}
diff --git a/src/test/compile-fail/associated-item-duplicate-names-3.rs b/src/test/compile-fail/associated-item-duplicate-names-3.rs
new file mode 100644
index 00000000000..7c4c5ca6b4e
--- /dev/null
+++ b/src/test/compile-fail/associated-item-duplicate-names-3.rs
@@ -0,0 +1,28 @@
+// 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;
+}
diff --git a/src/test/compile-fail/associated-item-duplicate-names.rs b/src/test/compile-fail/associated-item-duplicate-names.rs
new file mode 100644
index 00000000000..4c484b49024
--- /dev/null
+++ b/src/test/compile-fail/associated-item-duplicate-names.rs
@@ -0,0 +1,30 @@
+// 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;
+}