Skip to content

Commit ef9b9ce

Browse files
committed
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.
2 parents 8e9bd6c + 560bb0a commit ef9b9ce

File tree

5 files changed

+111
-15
lines changed

5 files changed

+111
-15
lines changed

src/librustc_typeck/collect.rs

+24-11
Original file line numberDiff line numberDiff line change
@@ -747,17 +747,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
747747
rcvr_ty_generics,
748748
rcvr_ty_predicates);
749749

750-
let tcx = ccx.tcx;
751-
let mut seen_methods = FnvHashSet();
752-
for (sig, id, ident, vis, span) in methods {
753-
if !seen_methods.insert(ident.name) {
754-
let fn_desc = match sig.explicit_self.node {
755-
ast::SelfStatic => "associated function",
756-
_ => "method",
757-
};
758-
span_err!(tcx.sess, span, E0201, "duplicate {}", fn_desc);
759-
}
760-
750+
for (sig, id, ident, vis, _span) in methods {
761751
convert_method(ccx,
762752
container,
763753
sig,
@@ -859,7 +849,30 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
859849
};
860850

861851
// Convert all the associated consts.
852+
// Also, check if there are any duplicate associated items
853+
let mut seen_type_items = FnvHashSet();
854+
let mut seen_value_items = FnvHashSet();
855+
862856
for impl_item in impl_items {
857+
let seen_items = match impl_item.node {
858+
ast::TypeImplItem(_) => &mut seen_type_items,
859+
_ => &mut seen_value_items,
860+
};
861+
if !seen_items.insert(impl_item.ident.name) {
862+
let desc = match impl_item.node {
863+
ast::ConstImplItem(_, _) => "associated constant",
864+
ast::TypeImplItem(_) => "associated type",
865+
ast::MethodImplItem(ref sig, _) =>
866+
match sig.explicit_self.node {
867+
ast::SelfStatic => "associated function",
868+
_ => "method",
869+
},
870+
_ => "associated item",
871+
};
872+
873+
span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
874+
}
875+
863876
if let ast::ConstImplItem(ref ty, ref expr) = impl_item.node {
864877
let ty = ccx.icx(&ty_predicates)
865878
.to_ty(&ExplicitRscope, &*ty);

src/librustc_typeck/diagnostics.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -1689,7 +1689,8 @@ unsafe impl Bar for Foo { }
16891689
"##,
16901690

16911691
E0201: r##"
1692-
It is an error to define an associated function more than once.
1692+
It is an error to define two associated items (like methods, associated types,
1693+
associated functions, etc.) with the same identifier.
16931694
16941695
For example:
16951696
@@ -1698,20 +1699,24 @@ struct Foo(u8);
16981699
16991700
impl Foo {
17001701
fn bar(&self) -> bool { self.0 > 5 }
1701-
1702-
// error: duplicate associated function
1703-
fn bar() {}
1702+
fn bar() {} // error: duplicate associated function
17041703
}
17051704
17061705
trait Baz {
1706+
type Quux;
17071707
fn baz(&self) -> bool;
17081708
}
17091709
17101710
impl Baz for Foo {
1711+
type Quux = u32;
1712+
17111713
fn baz(&self) -> bool { true }
17121714
17131715
// error: duplicate method
17141716
fn baz(&self) -> bool { self.0 > 5 }
1717+
1718+
// error: duplicate associated type
1719+
type Quux = u32;
17151720
}
17161721
```
17171722
"##,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
struct Foo;
14+
15+
impl Foo {
16+
const bar: bool = true;
17+
fn bar() {} //~ ERROR duplicate associated function
18+
}
19+
20+
fn main() {}
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
// Test for issue #23969
12+
13+
#![feature(associated_consts)]
14+
15+
trait Foo {
16+
type Ty;
17+
const BAR: u32;
18+
}
19+
20+
impl Foo for () {
21+
type Ty = ();
22+
type Ty = usize; //~ ERROR duplicate associated type
23+
const BAR: u32 = 7;
24+
const BAR: u32 = 8; //~ ERROR duplicate associated constant
25+
}
26+
27+
fn main() {
28+
let _: <() as Foo>::Ty = ();
29+
let _: u32 = <() as Foo>::BAR;
30+
}

0 commit comments

Comments
 (0)