Skip to content

Commit 857eb02

Browse files
committed
suggest fully qualified path with appropriate params
1 parent 9714e13 commit 857eb02

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

Diff for: compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
731731
// | help: specify type like: `<Impl as Into<u32>>::into(foo_impl)`
732732
// |
733733
// = note: cannot satisfy `Impl: Into<_>`
734+
debug!(?segment);
734735
if !impl_candidates.is_empty() && e.span.contains(span)
735736
&& let Some(expr) = exprs.first()
736737
&& let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
@@ -739,9 +740,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
739740
let mut eraser = TypeParamEraser(self.tcx);
740741
let candidate_len = impl_candidates.len();
741742
let mut suggestions: Vec<_> = impl_candidates.iter().map(|candidate| {
743+
let trait_item = self.tcx
744+
.associated_items(candidate.def_id)
745+
.find_by_name_and_kind(
746+
self.tcx,
747+
segment.ident,
748+
ty::AssocKind::Fn,
749+
candidate.def_id
750+
);
751+
let prefix = if let Some(trait_item) = trait_item
752+
&& let Some(trait_m) = trait_item.def_id.as_local()
753+
&& let hir::TraitItemKind::Fn(fn_, _) = &self.tcx.hir().trait_item(hir::TraitItemId { def_id: trait_m }).kind
754+
{
755+
match fn_.decl.implicit_self {
756+
hir::ImplicitSelfKind::ImmRef => "&",
757+
hir::ImplicitSelfKind::MutRef => "&mut ",
758+
_ => "",
759+
}
760+
} else {
761+
""
762+
};
742763
let candidate = candidate.super_fold_with(&mut eraser);
743764
vec![
744-
(expr.span.shrink_to_lo(), format!("{}::{}(", candidate, segment.ident)),
765+
(expr.span.shrink_to_lo(), format!("{}::{}({}", candidate, segment.ident, prefix)),
745766
if exprs.len() == 1 {
746767
(expr.span.shrink_to_hi().with_hi(e.span.hi()), ")".to_string())
747768
} else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
struct Thing;
2+
3+
trait Method<T> {
4+
fn method(&self) -> T;
5+
fn mut_method(&mut self) -> T;
6+
}
7+
8+
impl Method<i32> for Thing {
9+
fn method(&self) -> i32 { 0 }
10+
fn mut_method(&mut self) -> i32 { 0 }
11+
}
12+
13+
impl Method<u32> for Thing {
14+
fn method(&self) -> u32 { 0 }
15+
fn mut_method(&mut self) -> u32 { 0 }
16+
}
17+
18+
fn main() {
19+
let thing = Thing;
20+
thing.method();
21+
//~^ ERROR type annotations needed
22+
//~| ERROR type annotations needed
23+
thing.mut_method(); //~ ERROR type annotations needed
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:20:11
3+
|
4+
LL | thing.method();
5+
| ------^^^^^^--
6+
| | |
7+
| | cannot infer type for type parameter `T` declared on the trait `Method`
8+
| this method call resolves to `T`
9+
10+
error[E0283]: type annotations needed
11+
--> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:20:11
12+
|
13+
LL | thing.method();
14+
| ------^^^^^^--
15+
| | |
16+
| | cannot infer type for type parameter `T` declared on the trait `Method`
17+
| this method call resolves to `T`
18+
|
19+
note: multiple `impl`s satisfying `Thing: Method<_>` found
20+
--> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:8:1
21+
|
22+
LL | impl Method<i32> for Thing {
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
...
25+
LL | impl Method<u32> for Thing {
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
27+
help: use the fully qualified path for the potential candidates
28+
|
29+
LL | <Thing as Method<i32>>::method(&thing);
30+
| ++++++++++++++++++++++++++++++++ ~
31+
LL | <Thing as Method<u32>>::method(&thing);
32+
| ++++++++++++++++++++++++++++++++ ~
33+
34+
error[E0283]: type annotations needed
35+
--> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:23:11
36+
|
37+
LL | thing.mut_method();
38+
| ------^^^^^^^^^^--
39+
| | |
40+
| | cannot infer type for type parameter `T` declared on the trait `Method`
41+
| this method call resolves to `T`
42+
|
43+
note: multiple `impl`s satisfying `Thing: Method<_>` found
44+
--> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:8:1
45+
|
46+
LL | impl Method<i32> for Thing {
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
48+
...
49+
LL | impl Method<u32> for Thing {
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
51+
help: use the fully qualified path for the potential candidates
52+
|
53+
LL | <Thing as Method<i32>>::mut_method(&mut thing);
54+
| +++++++++++++++++++++++++++++++++++++++ ~
55+
LL | <Thing as Method<u32>>::mut_method(&mut thing);
56+
| +++++++++++++++++++++++++++++++++++++++ ~
57+
58+
error: aborting due to 3 previous errors
59+
60+
Some errors have detailed explanations: E0282, E0283.
61+
For more information about an error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)