Skip to content

Commit 5bbab89

Browse files
committed
distinguish the duplicate item of rpitit
1 parent 75d5834 commit 5bbab89

File tree

3 files changed

+112
-2
lines changed

3 files changed

+112
-2
lines changed

compiler/rustc_ty_utils/src/assoc.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,39 @@ fn associated_types_for_impl_traits_in_associated_fn(
195195
match tcx.def_kind(parent_def_id) {
196196
DefKind::Trait => {
197197
if let Some(output) = tcx.hir_get_fn_output(fn_def_id) {
198-
let data = DefPathData::AnonAssocTy(tcx.item_name(fn_def_id.to_def_id()));
198+
let def_path_id = |def_id: LocalDefId| tcx.item_name(def_id.to_def_id());
199+
let def_path_data = def_path_id(fn_def_id);
200+
201+
let (.., trait_item_refs) = tcx.hir_expect_item(parent_def_id).expect_trait();
202+
// The purpose of `disambiguator_idx` is to ensure there are
203+
// no duplicate `def_id` in certain cases, such as:
204+
// ```
205+
// trait Foo {
206+
// fn bar() -> impl Trait;
207+
// fn bar() -> impl Trait;
208+
// // ~~~~~~~~~~ It will generate the same ID if we don’t disambiguate it.
209+
// }
210+
// ```
211+
let disambiguator_idx = trait_item_refs
212+
.iter()
213+
.take_while(|item| item.id.owner_id.def_id != fn_def_id)
214+
.fold(0, |acc, item| {
215+
if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
216+
acc
217+
} else if def_path_id(item.id.owner_id.def_id) == def_path_data {
218+
tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator
219+
+ 1
220+
} else {
221+
acc
222+
}
223+
});
224+
225+
let data = DefPathData::AnonAssocTy(def_path_data);
199226
let mut visitor = RPITVisitor {
200227
tcx,
201228
synthetics: vec![],
202229
data,
203-
disambiguator: DisambiguatorState::with(parent_def_id, data, 0),
230+
disambiguator: DisambiguatorState::with(parent_def_id, data, disambiguator_idx),
204231
};
205232
visitor.visit_fn_ret_ty(output);
206233
tcx.arena.alloc_from_iter(
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// issue#140796
2+
3+
trait Bar {
4+
fn method() -> impl Sized;
5+
fn method() -> impl Sized; //~ ERROR: the name `method` is defined multiple times
6+
}
7+
8+
impl Bar for () { //~ ERROR: not all trait items implemented, missing: `method`
9+
fn method() -> impl Sized {
10+
42
11+
}
12+
fn method() -> impl Sized { //~ ERROR: duplicate definitions with name `method`
13+
42
14+
}
15+
}
16+
17+
trait T {
18+
fn method() -> impl Sized;
19+
}
20+
21+
impl T for () {
22+
fn method() -> impl Sized {
23+
42
24+
}
25+
fn method() -> impl Sized { //~ ERROR: duplicate definitions with name `method`
26+
42
27+
}
28+
}
29+
30+
fn main() {}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
error[E0428]: the name `method` is defined multiple times
2+
--> $DIR/rpitit-duplicate-associated-fn.rs:5:5
3+
|
4+
LL | fn method() -> impl Sized;
5+
| -------------------------- previous definition of the value `method` here
6+
LL | fn method() -> impl Sized;
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `method` redefined here
8+
|
9+
= note: `method` must be defined only once in the value namespace of this trait
10+
11+
error[E0201]: duplicate definitions with name `method`:
12+
--> $DIR/rpitit-duplicate-associated-fn.rs:12:5
13+
|
14+
LL | fn method() -> impl Sized;
15+
| -------------------------- item in trait
16+
...
17+
LL | / fn method() -> impl Sized {
18+
LL | | 42
19+
LL | | }
20+
| |_____- previous definition here
21+
LL | / fn method() -> impl Sized {
22+
LL | | 42
23+
LL | | }
24+
| |_____^ duplicate definition
25+
26+
error[E0201]: duplicate definitions with name `method`:
27+
--> $DIR/rpitit-duplicate-associated-fn.rs:25:5
28+
|
29+
LL | fn method() -> impl Sized;
30+
| -------------------------- item in trait
31+
...
32+
LL | / fn method() -> impl Sized {
33+
LL | | 42
34+
LL | | }
35+
| |_____- previous definition here
36+
LL | / fn method() -> impl Sized {
37+
LL | | 42
38+
LL | | }
39+
| |_____^ duplicate definition
40+
41+
error[E0046]: not all trait items implemented, missing: `method`
42+
--> $DIR/rpitit-duplicate-associated-fn.rs:8:1
43+
|
44+
LL | fn method() -> impl Sized;
45+
| -------------------------- `method` from trait
46+
...
47+
LL | impl Bar for () {
48+
| ^^^^^^^^^^^^^^^ missing `method` in implementation
49+
50+
error: aborting due to 4 previous errors
51+
52+
Some errors have detailed explanations: E0046, E0201, E0428.
53+
For more information about an error, try `rustc --explain E0046`.

0 commit comments

Comments
 (0)