Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a761f3d

Browse files
committedOct 16, 2023
review comments + more tests
1 parent a855178 commit a761f3d

9 files changed

+421
-20
lines changed
 

‎compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13401340
err,
13411341
path,
13421342
ty,
1343-
impl_ty,
1343+
Some(impl_ty),
13441344
item.kind,
13451345
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
13461346
sugg_span,
@@ -1377,7 +1377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13771377
err,
13781378
path,
13791379
rcvr_ty,
1380-
rcvr_ty,
1380+
None,
13811381
item.kind,
13821382
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
13831383
sugg_span,
@@ -3148,7 +3148,7 @@ fn print_disambiguation_help<'tcx>(
31483148
err: &mut Diagnostic,
31493149
trait_name: String,
31503150
rcvr_ty: Ty<'_>,
3151-
self_ty: Ty<'_>,
3151+
impl_self_ty: Option<Ty<'_>>,
31523152
kind: ty::AssocKind,
31533153
def_kind_descr: &'static str,
31543154
span: Span,
@@ -3174,20 +3174,21 @@ fn print_disambiguation_help<'tcx>(
31743174
.collect::<Vec<_>>()
31753175
.join(", "),
31763176
);
3177-
let trait_name = if !fn_has_self_parameter {
3178-
format!("<{self_ty} as {trait_name}>")
3177+
let trait_name = if !fn_has_self_parameter && let Some(impl_self_ty) = impl_self_ty {
3178+
format!("<{impl_self_ty} as {trait_name}>")
31793179
} else {
31803180
trait_name
31813181
};
31823182
(span, format!("{trait_name}::{item_name}{args}"))
3183+
} else if let Some(impl_self_ty) = impl_self_ty {
3184+
(span.with_hi(item_name.span.lo()), format!("<{impl_self_ty} as {trait_name}>::"))
31833185
} else {
3184-
(span.with_hi(item_name.span.lo()), format!("<{self_ty} as {trait_name}>::"))
3186+
(span.with_hi(item_name.span.lo()), format!("{trait_name}::"))
31853187
};
31863188
err.span_suggestion_verbose(
31873189
span,
31883190
format!(
3189-
"disambiguate the {} for {}",
3190-
def_kind_descr,
3191+
"disambiguate the {def_kind_descr} for {}",
31913192
if let Some(candidate) = candidate {
31923193
format!("candidate #{candidate}")
31933194
} else {

‎tests/ui/methods/disambiguate-multiple-blanket-impl.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
trait A {
2+
type Type;
3+
const CONST: usize;
24
fn foo(&self);
35
}
46

57
trait B {
8+
type Type;
9+
const CONST: usize;
610
fn foo(&self);
711
}
812

913
#[derive(Debug)]
1014
struct S;
1115

1216
impl<T: std::fmt::Debug> A for T {
17+
type Type = ();
18+
const CONST: usize = 1; //~ NOTE candidate #1
1319
fn foo(&self) {} //~ NOTE candidate #1
1420
}
1521

1622
impl<T: std::fmt::Debug> B for T {
23+
type Type = ();
24+
const CONST: usize = 2; //~ NOTE candidate #2
1725
fn foo(&self) {} //~ NOTE candidate #2
1826
}
1927

@@ -23,5 +31,10 @@ fn main() {
2331
//~^ NOTE multiple `foo` found
2432
//~| HELP disambiguate
2533
//~| HELP disambiguate
34+
S::CONST; //~ ERROR multiple applicable items in scope
35+
//~^ NOTE multiple `CONST` found
36+
//~| HELP disambiguate
37+
//~| HELP disambiguate
38+
let _: S::Type; //~ ERROR ambiguous associated type
39+
//~^ HELP use the fully-qualified path
2640
}
27-
Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
1+
error[E0223]: ambiguous associated type
2+
--> $DIR/disambiguate-multiple-blanket-impl.rs:38:12
3+
|
4+
LL | let _: S::Type;
5+
| ^^^^^^^
6+
|
7+
help: use the fully-qualified path
8+
|
9+
LL | let _: <S as A>::Type;
10+
| ~~~~~~~~~~~~~~
11+
LL | let _: <S as B>::Type;
12+
| ~~~~~~~~~~~~~~
13+
114
error[E0034]: multiple applicable items in scope
2-
--> $DIR/disambiguate-multiple-blanket-impl.rs:22:8
15+
--> $DIR/disambiguate-multiple-blanket-impl.rs:30:8
316
|
417
LL | S::foo(&s);
518
| ^^^ multiple `foo` found
619
|
720
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
8-
--> $DIR/disambiguate-multiple-blanket-impl.rs:13:5
21+
--> $DIR/disambiguate-multiple-blanket-impl.rs:19:5
922
|
1023
LL | fn foo(&self) {}
1124
| ^^^^^^^^^^^^^
1225
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
13-
--> $DIR/disambiguate-multiple-blanket-impl.rs:17:5
26+
--> $DIR/disambiguate-multiple-blanket-impl.rs:25:5
1427
|
1528
LL | fn foo(&self) {}
1629
| ^^^^^^^^^^^^^
@@ -23,6 +36,32 @@ help: disambiguate the method for candidate #2
2336
LL | <T as B>::foo(&s);
2437
| ~~~~~~~~~~
2538

26-
error: aborting due to previous error
39+
error[E0034]: multiple applicable items in scope
40+
--> $DIR/disambiguate-multiple-blanket-impl.rs:34:8
41+
|
42+
LL | S::CONST;
43+
| ^^^^^ multiple `CONST` found
44+
|
45+
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
46+
--> $DIR/disambiguate-multiple-blanket-impl.rs:18:5
47+
|
48+
LL | const CONST: usize = 1;
49+
| ^^^^^^^^^^^^^^^^^^
50+
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
51+
--> $DIR/disambiguate-multiple-blanket-impl.rs:24:5
52+
|
53+
LL | const CONST: usize = 2;
54+
| ^^^^^^^^^^^^^^^^^^
55+
help: disambiguate the associated constant for candidate #1
56+
|
57+
LL | <T as A>::CONST;
58+
| ~~~~~~~~~~
59+
help: disambiguate the associated constant for candidate #2
60+
|
61+
LL | <T as B>::CONST;
62+
| ~~~~~~~~~~
63+
64+
error: aborting due to 3 previous errors
2765

28-
For more information about this error, try `rustc --explain E0034`.
66+
Some errors have detailed explanations: E0034, E0223.
67+
For more information about an error, try `rustc --explain E0034`.

‎tests/ui/methods/disambiguate-multiple-impl.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
trait A {
2+
type Type;
3+
const CONST: usize;
24
fn foo(&self);
35
}
46

57
trait B {
8+
type Type;
9+
const CONST: usize;
610
fn foo(&self);
711
}
812

913
struct S;
1014

1115
impl A for S {
16+
type Type = ();
17+
const CONST: usize = 1; //~ NOTE candidate #1
1218
fn foo(&self) {} //~ NOTE candidate #1
1319
}
1420

1521
impl B for S {
22+
type Type = ();
23+
const CONST: usize = 2; //~ NOTE candidate #2
1624
fn foo(&self) {} //~ NOTE candidate #2
1725
}
1826

@@ -22,5 +30,10 @@ fn main() {
2230
//~^ NOTE multiple `foo` found
2331
//~| HELP disambiguate
2432
//~| HELP disambiguate
33+
let _: S::Type = (); //~ ERROR ambiguous associated type
34+
//~| HELP use the fully-qualified path
35+
let _ = S::CONST; //~ ERROR multiple applicable items in scope
36+
//~^ NOTE multiple `CONST` found
37+
//~| HELP disambiguate
38+
//~| HELP disambiguate
2539
}
26-
Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
1+
error[E0223]: ambiguous associated type
2+
--> $DIR/disambiguate-multiple-impl.rs:33:12
3+
|
4+
LL | let _: S::Type = ();
5+
| ^^^^^^^
6+
|
7+
help: use the fully-qualified path
8+
|
9+
LL | let _: <S as A>::Type = ();
10+
| ~~~~~~~~~~~~~~
11+
LL | let _: <S as B>::Type = ();
12+
| ~~~~~~~~~~~~~~
13+
114
error[E0034]: multiple applicable items in scope
2-
--> $DIR/disambiguate-multiple-impl.rs:21:8
15+
--> $DIR/disambiguate-multiple-impl.rs:29:8
316
|
417
LL | S::foo(&s);
518
| ^^^ multiple `foo` found
619
|
720
note: candidate #1 is defined in an impl of the trait `A` for the type `S`
8-
--> $DIR/disambiguate-multiple-impl.rs:12:5
21+
--> $DIR/disambiguate-multiple-impl.rs:18:5
922
|
1023
LL | fn foo(&self) {}
1124
| ^^^^^^^^^^^^^
1225
note: candidate #2 is defined in an impl of the trait `B` for the type `S`
13-
--> $DIR/disambiguate-multiple-impl.rs:16:5
26+
--> $DIR/disambiguate-multiple-impl.rs:24:5
1427
|
1528
LL | fn foo(&self) {}
1629
| ^^^^^^^^^^^^^
@@ -23,6 +36,32 @@ help: disambiguate the method for candidate #2
2336
LL | <S as B>::foo(&s);
2437
| ~~~~~~~~~~
2538

26-
error: aborting due to previous error
39+
error[E0034]: multiple applicable items in scope
40+
--> $DIR/disambiguate-multiple-impl.rs:35:16
41+
|
42+
LL | let _ = S::CONST;
43+
| ^^^^^ multiple `CONST` found
44+
|
45+
note: candidate #1 is defined in an impl of the trait `A` for the type `S`
46+
--> $DIR/disambiguate-multiple-impl.rs:17:5
47+
|
48+
LL | const CONST: usize = 1;
49+
| ^^^^^^^^^^^^^^^^^^
50+
note: candidate #2 is defined in an impl of the trait `B` for the type `S`
51+
--> $DIR/disambiguate-multiple-impl.rs:23:5
52+
|
53+
LL | const CONST: usize = 2;
54+
| ^^^^^^^^^^^^^^^^^^
55+
help: disambiguate the associated constant for candidate #1
56+
|
57+
LL | let _ = <S as A>::CONST;
58+
| ~~~~~~~~~~
59+
help: disambiguate the associated constant for candidate #2
60+
|
61+
LL | let _ = <S as B>::CONST;
62+
| ~~~~~~~~~~
63+
64+
error: aborting due to 3 previous errors
2765

28-
For more information about this error, try `rustc --explain E0034`.
66+
Some errors have detailed explanations: E0034, E0223.
67+
For more information about an error, try `rustc --explain E0034`.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
trait A {
2+
type Type; //~ NOTE ambiguous `Type` from `A`
3+
const CONST: usize = 1; //~ NOTE candidate #1
4+
fn foo(&self); //~ NOTE candidate #1
5+
}
6+
7+
trait B {
8+
type Type; //~ NOTE ambiguous `Type` from `B`
9+
const CONST: usize; //~ NOTE candidate #2
10+
fn foo(&self); //~ NOTE candidate #2
11+
}
12+
13+
trait C: A + B {}
14+
15+
fn a<T: C>(t: T) {
16+
t.foo(); //~ ERROR multiple applicable items in scope
17+
//~^ NOTE multiple `foo` found
18+
//~| HELP disambiguate the method
19+
//~| HELP disambiguate the method
20+
let _ = T::CONST; //~ ERROR multiple applicable items in scope
21+
//~^ NOTE multiple `CONST` found
22+
//~| HELP disambiguate
23+
//~| HELP disambiguate
24+
let _: T::Type; //~ ERROR ambiguous associated type
25+
//~^ NOTE ambiguous associated type `Type`
26+
//~| HELP use fully qualified syntax
27+
//~| HELP use fully qualified syntax
28+
}
29+
30+
#[derive(Debug)]
31+
struct S;
32+
33+
impl<T: std::fmt::Debug> A for T {
34+
type Type = ();
35+
const CONST: usize = 1; //~ NOTE candidate #1
36+
fn foo(&self) {} //~ NOTE candidate #1
37+
}
38+
39+
impl<T: std::fmt::Debug> B for T {
40+
type Type = ();
41+
const CONST: usize = 1; //~ NOTE candidate #2
42+
fn foo(&self) {} //~ NOTE candidate #2
43+
}
44+
45+
fn main() {
46+
let s = S;
47+
S::foo(&s); //~ ERROR multiple applicable items in scope
48+
//~^ NOTE multiple `foo` found
49+
//~| HELP disambiguate
50+
//~| HELP disambiguate
51+
let _ = S::CONST; //~ ERROR multiple applicable items in scope
52+
//~^ NOTE multiple `CONST` found
53+
//~| HELP disambiguate
54+
//~| HELP disambiguate
55+
let _: S::Type; //~ ERROR ambiguous associated type
56+
//~^ HELP use the fully-qualified path
57+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
error[E0221]: ambiguous associated type `Type` in bounds of `T`
2+
--> $DIR/disambiguate-multiple-trait-2.rs:24:12
3+
|
4+
LL | type Type;
5+
| --------- ambiguous `Type` from `A`
6+
...
7+
LL | type Type;
8+
| --------- ambiguous `Type` from `B`
9+
...
10+
LL | let _: T::Type;
11+
| ^^^^^^^ ambiguous associated type `Type`
12+
|
13+
help: use fully qualified syntax to disambiguate
14+
|
15+
LL | let _: <T as A>::Type;
16+
| ~~~~~~~~~~
17+
help: use fully qualified syntax to disambiguate
18+
|
19+
LL | let _: <T as B>::Type;
20+
| ~~~~~~~~~~
21+
22+
error[E0034]: multiple applicable items in scope
23+
--> $DIR/disambiguate-multiple-trait-2.rs:16:7
24+
|
25+
LL | t.foo();
26+
| ^^^ multiple `foo` found
27+
|
28+
note: candidate #1 is defined in the trait `A`
29+
--> $DIR/disambiguate-multiple-trait-2.rs:4:5
30+
|
31+
LL | fn foo(&self);
32+
| ^^^^^^^^^^^^^^
33+
note: candidate #2 is defined in the trait `B`
34+
--> $DIR/disambiguate-multiple-trait-2.rs:10:5
35+
|
36+
LL | fn foo(&self);
37+
| ^^^^^^^^^^^^^^
38+
help: disambiguate the method for candidate #1
39+
|
40+
LL | A::foo(t);
41+
| ~~~~~~~~~
42+
help: disambiguate the method for candidate #2
43+
|
44+
LL | B::foo(t);
45+
| ~~~~~~~~~
46+
47+
error[E0034]: multiple applicable items in scope
48+
--> $DIR/disambiguate-multiple-trait-2.rs:20:16
49+
|
50+
LL | let _ = T::CONST;
51+
| ^^^^^ multiple `CONST` found
52+
|
53+
note: candidate #1 is defined in the trait `A`
54+
--> $DIR/disambiguate-multiple-trait-2.rs:3:5
55+
|
56+
LL | const CONST: usize = 1;
57+
| ^^^^^^^^^^^^^^^^^^
58+
note: candidate #2 is defined in the trait `B`
59+
--> $DIR/disambiguate-multiple-trait-2.rs:9:5
60+
|
61+
LL | const CONST: usize;
62+
| ^^^^^^^^^^^^^^^^^^
63+
help: disambiguate the associated constant for candidate #1
64+
|
65+
LL | let _ = A::CONST;
66+
| ~~~
67+
help: disambiguate the associated constant for candidate #2
68+
|
69+
LL | let _ = B::CONST;
70+
| ~~~
71+
72+
error[E0223]: ambiguous associated type
73+
--> $DIR/disambiguate-multiple-trait-2.rs:55:12
74+
|
75+
LL | let _: S::Type;
76+
| ^^^^^^^
77+
|
78+
help: use the fully-qualified path
79+
|
80+
LL | let _: <S as A>::Type;
81+
| ~~~~~~~~~~~~~~
82+
LL | let _: <S as B>::Type;
83+
| ~~~~~~~~~~~~~~
84+
85+
error[E0034]: multiple applicable items in scope
86+
--> $DIR/disambiguate-multiple-trait-2.rs:47:8
87+
|
88+
LL | S::foo(&s);
89+
| ^^^ multiple `foo` found
90+
|
91+
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
92+
--> $DIR/disambiguate-multiple-trait-2.rs:36:5
93+
|
94+
LL | fn foo(&self) {}
95+
| ^^^^^^^^^^^^^
96+
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
97+
--> $DIR/disambiguate-multiple-trait-2.rs:42:5
98+
|
99+
LL | fn foo(&self) {}
100+
| ^^^^^^^^^^^^^
101+
help: disambiguate the method for candidate #1
102+
|
103+
LL | <T as A>::foo(&s);
104+
| ~~~~~~~~~~
105+
help: disambiguate the method for candidate #2
106+
|
107+
LL | <T as B>::foo(&s);
108+
| ~~~~~~~~~~
109+
110+
error[E0034]: multiple applicable items in scope
111+
--> $DIR/disambiguate-multiple-trait-2.rs:51:16
112+
|
113+
LL | let _ = S::CONST;
114+
| ^^^^^ multiple `CONST` found
115+
|
116+
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
117+
--> $DIR/disambiguate-multiple-trait-2.rs:35:5
118+
|
119+
LL | const CONST: usize = 1;
120+
| ^^^^^^^^^^^^^^^^^^
121+
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
122+
--> $DIR/disambiguate-multiple-trait-2.rs:41:5
123+
|
124+
LL | const CONST: usize = 1;
125+
| ^^^^^^^^^^^^^^^^^^
126+
help: disambiguate the associated constant for candidate #1
127+
|
128+
LL | let _ = <T as A>::CONST;
129+
| ~~~~~~~~~~
130+
help: disambiguate the associated constant for candidate #2
131+
|
132+
LL | let _ = <T as B>::CONST;
133+
| ~~~~~~~~~~
134+
135+
error: aborting due to 6 previous errors
136+
137+
Some errors have detailed explanations: E0034, E0221, E0223.
138+
For more information about an error, try `rustc --explain E0034`.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#![feature(associated_type_defaults)]
2+
3+
trait A {
4+
type Type = ();
5+
const CONST: usize = 1; //~ NOTE candidate #1
6+
fn foo(&self) {} //~ NOTE candidate #1
7+
}
8+
9+
trait B {
10+
type Type = ();
11+
const CONST: usize = 2; //~ NOTE candidate #2
12+
fn foo(&self) {} //~ NOTE candidate #2
13+
}
14+
15+
#[derive(Debug)]
16+
struct S;
17+
18+
impl<T: std::fmt::Debug> A for T {}
19+
20+
impl<T: std::fmt::Debug> B for T {}
21+
22+
fn main() {
23+
let s = S;
24+
S::foo(&s); //~ ERROR multiple applicable items in scope
25+
//~^ NOTE multiple `foo` found
26+
//~| HELP disambiguate
27+
//~| HELP disambiguate
28+
let _ = S::CONST; //~ ERROR multiple applicable items in scope
29+
//~^ NOTE multiple `CONST` found
30+
//~| HELP disambiguate
31+
//~| HELP disambiguate
32+
let _: S::Type; //~ ERROR ambiguous associated type
33+
//~^ HELP use the fully-qualified path
34+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
error[E0223]: ambiguous associated type
2+
--> $DIR/disambiguate-multiple-trait.rs:32:12
3+
|
4+
LL | let _: S::Type;
5+
| ^^^^^^^
6+
|
7+
help: use the fully-qualified path
8+
|
9+
LL | let _: <S as A>::Type;
10+
| ~~~~~~~~~~~~~~
11+
LL | let _: <S as B>::Type;
12+
| ~~~~~~~~~~~~~~
13+
14+
error[E0034]: multiple applicable items in scope
15+
--> $DIR/disambiguate-multiple-trait.rs:24:8
16+
|
17+
LL | S::foo(&s);
18+
| ^^^ multiple `foo` found
19+
|
20+
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
21+
--> $DIR/disambiguate-multiple-trait.rs:6:5
22+
|
23+
LL | fn foo(&self) {}
24+
| ^^^^^^^^^^^^^
25+
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
26+
--> $DIR/disambiguate-multiple-trait.rs:12:5
27+
|
28+
LL | fn foo(&self) {}
29+
| ^^^^^^^^^^^^^
30+
help: disambiguate the method for candidate #1
31+
|
32+
LL | <T as A>::foo(&s);
33+
| ~~~~~~~~~~
34+
help: disambiguate the method for candidate #2
35+
|
36+
LL | <T as B>::foo(&s);
37+
| ~~~~~~~~~~
38+
39+
error[E0034]: multiple applicable items in scope
40+
--> $DIR/disambiguate-multiple-trait.rs:28:16
41+
|
42+
LL | let _ = S::CONST;
43+
| ^^^^^ multiple `CONST` found
44+
|
45+
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
46+
--> $DIR/disambiguate-multiple-trait.rs:5:5
47+
|
48+
LL | const CONST: usize = 1;
49+
| ^^^^^^^^^^^^^^^^^^
50+
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
51+
--> $DIR/disambiguate-multiple-trait.rs:11:5
52+
|
53+
LL | const CONST: usize = 2;
54+
| ^^^^^^^^^^^^^^^^^^
55+
help: disambiguate the associated constant for candidate #1
56+
|
57+
LL | let _ = <T as A>::CONST;
58+
| ~~~~~~~~~~
59+
help: disambiguate the associated constant for candidate #2
60+
|
61+
LL | let _ = <T as B>::CONST;
62+
| ~~~~~~~~~~
63+
64+
error: aborting due to 3 previous errors
65+
66+
Some errors have detailed explanations: E0034, E0223.
67+
For more information about an error, try `rustc --explain E0034`.

0 commit comments

Comments
 (0)
Please sign in to comment.