Skip to content

Commit 6cf01fc

Browse files
committed
review comments + more tests
1 parent 5cc9216 commit 6cf01fc

9 files changed

+421
-20
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

+9-8
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

+14-1
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-
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

+14-1
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-
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`.
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+
}

0 commit comments

Comments
 (0)