Skip to content

Commit a4e05e1

Browse files
authored
Rollup merge of #143570 - bvanjoi:issue-143560, r=compiler-errors
consider nested cases for duplicate RPITIT Fixes #143560 r? `@compiler-errors` cc `@Zoxc`
2 parents 40e1ccf + e1720d7 commit a4e05e1

File tree

5 files changed

+162
-11
lines changed

5 files changed

+162
-11
lines changed

compiler/rustc_ty_utils/src/assoc.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
177177
}
178178
}
179179

180+
struct DisambiguatorIdxVisitor {
181+
depth: u32,
182+
}
183+
184+
impl<'tcx> Visitor<'tcx> for DisambiguatorIdxVisitor {
185+
fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result {
186+
self.depth += 1;
187+
intravisit::walk_opaque_ty(self, opaque)
188+
}
189+
}
190+
180191
/// Given an `fn_def_id` of a trait or a trait implementation:
181192
///
182193
/// if `fn_def_id` is a function defined inside a trait, then it synthesizes
@@ -211,16 +222,19 @@ fn associated_types_for_impl_traits_in_associated_fn(
211222
let disambiguator_idx = trait_item_refs
212223
.iter()
213224
.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-
});
225+
.filter(|item| {
226+
matches!(item.kind, hir::AssocItemKind::Fn { .. })
227+
&& def_path_id(item.id.owner_id.def_id) == def_path_data
228+
})
229+
.last()
230+
.map(|item| {
231+
let output = tcx.hir_get_fn_output(item.id.owner_id.def_id).unwrap();
232+
let mut visitor = DisambiguatorIdxVisitor { depth: 0 };
233+
visitor.visit_fn_ret_ty(output);
234+
tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator
235+
+ visitor.depth
236+
})
237+
.unwrap_or_default();
224238

225239
let data = DefPathData::AnonAssocTy(def_path_data);
226240
let mut visitor = RPITVisitor {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// issue#143560
2+
3+
trait T {
4+
type Target;
5+
}
6+
7+
trait Foo {
8+
fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
9+
fn foo() -> impl Sized;
10+
//~^ ERROR: the name `foo` is defined multiple times
11+
}
12+
13+
trait Bar {
14+
fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
15+
fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
16+
//~^ ERROR: the name `foo` is defined multiple times
17+
}
18+
19+
struct S<T> {
20+
a: T
21+
}
22+
23+
trait Baz {
24+
fn foo() -> S<impl T<Target = S<S<impl Sized>>>>;
25+
fn foo() -> S<impl T<Target = S<S<impl Sized>>>>;
26+
//~^ ERROR: the name `foo` is defined multiple times
27+
}
28+
29+
struct S1<T1, T2> {
30+
a: T1,
31+
b: T2
32+
}
33+
34+
trait Qux {
35+
fn foo() -> S1<
36+
impl T<Target = impl T<Target = impl Sized>>,
37+
impl T<Target = impl T<Target = S<impl Sized>>>
38+
>;
39+
fn foo() -> S1<
40+
impl T<Target = impl T<Target = impl Sized>>,
41+
impl T<Target = impl T<Target = S<impl Sized>>>
42+
>;
43+
//~^^^^ ERROR: the name `foo` is defined multiple times
44+
}
45+
46+
fn main() {}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
error[E0428]: the name `foo` is defined multiple times
2+
--> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:9:5
3+
|
4+
LL | fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
5+
| --------------------------------------------------------- previous definition of the value `foo` here
6+
LL | fn foo() -> impl Sized;
7+
| ^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
8+
|
9+
= note: `foo` must be defined only once in the value namespace of this trait
10+
11+
error[E0428]: the name `foo` is defined multiple times
12+
--> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:15:5
13+
|
14+
LL | fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
15+
| --------------------------------------------------------- previous definition of the value `foo` here
16+
LL | fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
18+
|
19+
= note: `foo` must be defined only once in the value namespace of this trait
20+
21+
error[E0428]: the name `foo` is defined multiple times
22+
--> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:25:5
23+
|
24+
LL | fn foo() -> S<impl T<Target = S<S<impl Sized>>>>;
25+
| ------------------------------------------------- previous definition of the value `foo` here
26+
LL | fn foo() -> S<impl T<Target = S<S<impl Sized>>>>;
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
28+
|
29+
= note: `foo` must be defined only once in the value namespace of this trait
30+
31+
error[E0428]: the name `foo` is defined multiple times
32+
--> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:39:5
33+
|
34+
LL | / fn foo() -> S1<
35+
LL | | impl T<Target = impl T<Target = impl Sized>>,
36+
LL | | impl T<Target = impl T<Target = S<impl Sized>>>
37+
LL | | >;
38+
| |__________- previous definition of the value `foo` here
39+
LL | / fn foo() -> S1<
40+
LL | | impl T<Target = impl T<Target = impl Sized>>,
41+
LL | | impl T<Target = impl T<Target = S<impl Sized>>>
42+
LL | | >;
43+
| |__________^ `foo` redefined here
44+
|
45+
= note: `foo` must be defined only once in the value namespace of this trait
46+
47+
error: aborting due to 4 previous errors
48+
49+
For more information about this error, try `rustc --explain E0428`.

tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,15 @@ impl T for () {
2727
}
2828
}
2929

30+
trait Baz {
31+
fn foo();
32+
fn foo() -> impl Sized; //~ ERROR: the name `foo` is defined multiple times
33+
}
34+
35+
trait Foo {
36+
fn foo() -> impl Sized;
37+
fn foo(); //~ ERROR: the name `foo` is defined multiple times
38+
fn foo() -> impl Sized; //~ ERROR: the name `foo` is defined multiple times
39+
}
40+
3041
fn main() {}

tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.stderr

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,37 @@ LL | fn method() -> impl Sized;
88
|
99
= note: `method` must be defined only once in the value namespace of this trait
1010

11+
error[E0428]: the name `foo` is defined multiple times
12+
--> $DIR/rpitit-duplicate-associated-fn.rs:32:5
13+
|
14+
LL | fn foo();
15+
| --------- previous definition of the value `foo` here
16+
LL | fn foo() -> impl Sized;
17+
| ^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
18+
|
19+
= note: `foo` must be defined only once in the value namespace of this trait
20+
21+
error[E0428]: the name `foo` is defined multiple times
22+
--> $DIR/rpitit-duplicate-associated-fn.rs:37:5
23+
|
24+
LL | fn foo() -> impl Sized;
25+
| ----------------------- previous definition of the value `foo` here
26+
LL | fn foo();
27+
| ^^^^^^^^^ `foo` redefined here
28+
|
29+
= note: `foo` must be defined only once in the value namespace of this trait
30+
31+
error[E0428]: the name `foo` is defined multiple times
32+
--> $DIR/rpitit-duplicate-associated-fn.rs:38:5
33+
|
34+
LL | fn foo() -> impl Sized;
35+
| ----------------------- previous definition of the value `foo` here
36+
LL | fn foo();
37+
LL | fn foo() -> impl Sized;
38+
| ^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
39+
|
40+
= note: `foo` must be defined only once in the value namespace of this trait
41+
1142
error[E0201]: duplicate definitions with name `method`:
1243
--> $DIR/rpitit-duplicate-associated-fn.rs:12:5
1344
|
@@ -47,7 +78,7 @@ LL | fn method() -> impl Sized;
4778
LL | impl Bar for () {
4879
| ^^^^^^^^^^^^^^^ missing `method` in implementation
4980

50-
error: aborting due to 4 previous errors
81+
error: aborting due to 7 previous errors
5182

5283
Some errors have detailed explanations: E0046, E0201, E0428.
5384
For more information about an error, try `rustc --explain E0046`.

0 commit comments

Comments
 (0)