Skip to content

Commit 70255ef

Browse files
committed
On single local candidate, use span label
1 parent 24bfa16 commit 70255ef

14 files changed

+95
-59
lines changed

src/librustc_typeck/check/method/suggest.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
846846
let message = |action| {
847847
format!(
848848
"the following {traits_define} an item `{name}`, perhaps you need to {action} \
849-
{one_of_them}:",
849+
{one_of_them}:",
850850
traits_define =
851851
if candidates.len() == 1 { "trait defines" } else { "traits define" },
852852
action = action,
@@ -944,19 +944,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
944944
}
945945

946946
if !suggested {
947-
let mut msg = message(if let Some(param) = param_type {
947+
let action = if let Some(param) = param_type {
948948
format!("restrict type parameter `{}` with", param)
949949
} else {
950950
"implement".to_string()
951-
});
952-
for (i, trait_info) in candidates.iter().enumerate() {
953-
msg.push_str(&format!(
954-
"\ncandidate #{}: `{}`",
955-
i + 1,
956-
self.tcx.def_path_str(trait_info.def_id),
957-
));
951+
};
952+
let mut use_note = true;
953+
if let [trait_info] = &candidates[..] {
954+
if let Some(span) = self.tcx.hir().span_if_local(trait_info.def_id) {
955+
err.span_label(
956+
self.tcx.sess.source_map().def_span(span),
957+
&format!("this trait defines an item `{}`", item_name),
958+
);
959+
use_note = false
960+
}
961+
}
962+
if use_note {
963+
let mut msg = message(action);
964+
for (i, trait_info) in candidates.iter().enumerate() {
965+
msg.push_str(&format!(
966+
"\ncandidate #{}: `{}`",
967+
i + 1,
968+
self.tcx.def_path_str(trait_info.def_id),
969+
));
970+
}
971+
err.note(&msg[..]);
958972
}
959-
err.note(&msg[..]);
960973
}
961974
}
962975
}

src/test/ui/associated-const/associated-const-no-item.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
error[E0599]: no associated item named `ID` found for type `i32` in the current scope
22
--> $DIR/associated-const-no-item.rs:5:23
33
|
4+
LL | trait Foo {
5+
| --------- this trait defines an item `ID`
6+
...
47
LL | const X: i32 = <i32>::ID;
58
| ^^ associated item not found in `i32`
69
|
710
= help: items from traits can only be used if the trait is implemented and in scope
8-
= note: the following trait defines an item `ID`, perhaps you need to implement it:
9-
candidate #1: `Foo`
1011

1112
error: aborting due to previous error
1213

src/test/ui/auto-ref-slice-plus-ref.stderr

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,44 @@ error[E0599]: no method named `test_mut` found for struct `std::vec::Vec<{intege
33
|
44
LL | a.test_mut();
55
| ^^^^^^^^ help: there is a method with a similar name: `get_mut`
6+
...
7+
LL | trait MyIter {
8+
| ------------ this trait defines an item `test_mut`
69
|
710
= help: items from traits can only be used if the trait is implemented and in scope
8-
= note: the following trait defines an item `test_mut`, perhaps you need to implement it:
9-
candidate #1: `MyIter`
1011

1112
error[E0599]: no method named `test` found for struct `std::vec::Vec<{integer}>` in the current scope
1213
--> $DIR/auto-ref-slice-plus-ref.rs:8:7
1314
|
1415
LL | a.test();
1516
| ^^^^ method not found in `std::vec::Vec<{integer}>`
17+
...
18+
LL | trait MyIter {
19+
| ------------ this trait defines an item `test`
1620
|
1721
= help: items from traits can only be used if the trait is implemented and in scope
18-
= note: the following trait defines an item `test`, perhaps you need to implement it:
19-
candidate #1: `MyIter`
2022

2123
error[E0599]: no method named `test` found for array `[{integer}; 1]` in the current scope
2224
--> $DIR/auto-ref-slice-plus-ref.rs:10:11
2325
|
2426
LL | ([1]).test();
2527
| ^^^^ method not found in `[{integer}; 1]`
28+
...
29+
LL | trait MyIter {
30+
| ------------ this trait defines an item `test`
2631
|
2732
= help: items from traits can only be used if the trait is implemented and in scope
28-
= note: the following trait defines an item `test`, perhaps you need to implement it:
29-
candidate #1: `MyIter`
3033

3134
error[E0599]: no method named `test` found for reference `&[{integer}; 1]` in the current scope
3235
--> $DIR/auto-ref-slice-plus-ref.rs:11:12
3336
|
3437
LL | (&[1]).test();
3538
| ^^^^ method not found in `&[{integer}; 1]`
39+
...
40+
LL | trait MyIter {
41+
| ------------ this trait defines an item `test`
3642
|
3743
= help: items from traits can only be used if the trait is implemented and in scope
38-
= note: the following trait defines an item `test`, perhaps you need to implement it:
39-
candidate #1: `MyIter`
4044

4145
error: aborting due to 4 previous errors
4246

src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
error[E0599]: no method named `foo` found for struct `Bar` in the current scope
22
--> $DIR/issue-21659-show-relevant-trait-impls-3.rs:20:8
33
|
4+
LL | trait Foo<A> {
5+
| ------------ this trait defines an item `foo`
6+
...
47
LL | struct Bar;
58
| ----------- method `foo` not found for this
69
...
710
LL | f1.foo(1usize);
811
| ^^^ method not found in `Bar`
912
|
1013
= help: items from traits can only be used if the trait is implemented and in scope
11-
= note: the following trait defines an item `foo`, perhaps you need to implement it:
12-
candidate #1: `Foo`
1314

1415
error: aborting due to previous error
1516

src/test/ui/impl-trait/no-method-suggested-traits.stderr

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,62 +122,68 @@ LL | std::rc::Rc::new(&mut Box::new(&Foo)).method();
122122
error[E0599]: no method named `method2` found for type `u64` in the current scope
123123
--> $DIR/no-method-suggested-traits.rs:45:10
124124
|
125+
LL | pub trait Bar {
126+
| ------------- this trait defines an item `method2`
127+
...
125128
LL | 1u64.method2();
126129
| ^^^^^^^ method not found in `u64`
127130
|
128131
= help: items from traits can only be used if the trait is implemented and in scope
129-
= note: the following trait defines an item `method2`, perhaps you need to implement it:
130-
candidate #1: `foo::Bar`
131132

132133
error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&u64>>` in the current scope
133134
--> $DIR/no-method-suggested-traits.rs:47:44
134135
|
136+
LL | pub trait Bar {
137+
| ------------- this trait defines an item `method2`
138+
...
135139
LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2();
136140
| ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&u64>>`
137141
|
138142
= help: items from traits can only be used if the trait is implemented and in scope
139-
= note: the following trait defines an item `method2`, perhaps you need to implement it:
140-
candidate #1: `foo::Bar`
141143

142144
error[E0599]: no method named `method2` found for struct `no_method_suggested_traits::Foo` in the current scope
143145
--> $DIR/no-method-suggested-traits.rs:50:37
144146
|
147+
LL | pub trait Bar {
148+
| ------------- this trait defines an item `method2`
149+
...
145150
LL | no_method_suggested_traits::Foo.method2();
146151
| ^^^^^^^ method not found in `no_method_suggested_traits::Foo`
147152
|
148153
= help: items from traits can only be used if the trait is implemented and in scope
149-
= note: the following trait defines an item `method2`, perhaps you need to implement it:
150-
candidate #1: `foo::Bar`
151154

152155
error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope
153156
--> $DIR/no-method-suggested-traits.rs:52:71
154157
|
158+
LL | pub trait Bar {
159+
| ------------- this trait defines an item `method2`
160+
...
155161
LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2();
156162
| ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>`
157163
|
158164
= help: items from traits can only be used if the trait is implemented and in scope
159-
= note: the following trait defines an item `method2`, perhaps you need to implement it:
160-
candidate #1: `foo::Bar`
161165

162166
error[E0599]: no method named `method2` found for enum `no_method_suggested_traits::Bar` in the current scope
163167
--> $DIR/no-method-suggested-traits.rs:54:40
164168
|
169+
LL | pub trait Bar {
170+
| ------------- this trait defines an item `method2`
171+
...
165172
LL | no_method_suggested_traits::Bar::X.method2();
166173
| ^^^^^^^ method not found in `no_method_suggested_traits::Bar`
167174
|
168175
= help: items from traits can only be used if the trait is implemented and in scope
169-
= note: the following trait defines an item `method2`, perhaps you need to implement it:
170-
candidate #1: `foo::Bar`
171176

172177
error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope
173178
--> $DIR/no-method-suggested-traits.rs:56:74
174179
|
180+
LL | pub trait Bar {
181+
| ------------- this trait defines an item `method2`
182+
...
175183
LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2();
176184
| ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>`
177185
|
178186
= help: items from traits can only be used if the trait is implemented and in scope
179-
= note: the following trait defines an item `method2`, perhaps you need to implement it:
180-
candidate #1: `foo::Bar`
181187

182188
error[E0599]: no method named `method3` found for struct `Foo` in the current scope
183189
--> $DIR/no-method-suggested-traits.rs:59:9

src/test/ui/issues/issue-5153.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
error[E0599]: no method named `foo` found for reference `&dyn Foo` in the current scope
22
--> $DIR/issue-5153.rs:10:27
33
|
4+
LL | trait Foo {
5+
| --------- this trait defines an item `foo`
6+
...
47
LL | (&5isize as &dyn Foo).foo();
58
| ^^^ method not found in `&dyn Foo`
69
|
710
= help: items from traits can only be used if the trait is implemented and in scope
8-
= note: the following trait defines an item `foo`, perhaps you need to implement it:
9-
candidate #1: `Foo`
1011

1112
error: aborting due to previous error
1213

src/test/ui/issues/issue-57362-1.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current scope
22
--> $DIR/issue-57362-1.rs:20:7
33
|
4+
LL | trait Trait {
5+
| ----------- this trait defines an item `f`
6+
...
47
LL | a.f();
58
| ^ method not found in `fn(&u8)`
69
|
710
= note: `a` is a function, perhaps you wish to call it
811
= help: items from traits can only be used if the trait is implemented and in scope
9-
= note: the following trait defines an item `f`, perhaps you need to implement it:
10-
candidate #1: `Trait`
1112

1213
error: aborting due to previous error
1314

src/test/ui/issues/issue-57362-2.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'r> fn(&'r ())` in the current scope
22
--> $DIR/issue-57362-2.rs:22:25
33
|
4+
LL | trait X {
5+
| ------- this trait defines an item `make_g`
6+
...
47
LL | let x = <fn (&())>::make_g();
58
| ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())`
69
|
710
= help: items from traits can only be used if the trait is implemented and in scope
8-
= note: the following trait defines an item `make_g`, perhaps you need to implement it:
9-
candidate #1: `X`
1011

1112
error: aborting due to previous error
1213

src/test/ui/never_type/issue-2149.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ LL | for elt in self { r = r + f(*elt); }
99
error[E0599]: no method named `bind` found for array `[&str; 1]` in the current scope
1010
--> $DIR/issue-2149.rs:13:12
1111
|
12+
LL | trait VecMonad<A> {
13+
| ----------------- this trait defines an item `bind`
14+
...
1215
LL | ["hi"].bind(|x| [x] );
1316
| ^^^^ method not found in `[&str; 1]`
1417
|
1518
= help: items from traits can only be used if the trait is implemented and in scope
16-
= note: the following trait defines an item `bind`, perhaps you need to implement it:
17-
candidate #1: `VecMonad`
1819

1920
error: aborting due to 2 previous errors
2021

src/test/ui/object-pointer-types.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
error[E0599]: no method named `owned` found for reference `&dyn Foo` in the current scope
22
--> $DIR/object-pointer-types.rs:11:7
33
|
4+
LL | trait Foo {
5+
| --------- this trait defines an item `owned`
6+
...
47
LL | x.owned();
58
| ^^^^^ method not found in `&dyn Foo`
69
|
710
= help: items from traits can only be used if the trait is implemented and in scope
8-
= note: the following trait defines an item `owned`, perhaps you need to implement it:
9-
candidate #1: `Foo`
1011

1112
error[E0599]: no method named `owned` found for mutable reference `&mut dyn Foo` in the current scope
1213
--> $DIR/object-pointer-types.rs:17:7
1314
|
15+
LL | trait Foo {
16+
| --------- this trait defines an item `owned`
17+
...
1418
LL | x.owned();
1519
| ^^^^^ method not found in `&mut dyn Foo`
1620
|
1721
= help: items from traits can only be used if the trait is implemented and in scope
18-
= note: the following trait defines an item `owned`, perhaps you need to implement it:
19-
candidate #1: `Foo`
2022

2123
error[E0599]: no method named `managed` found for struct `std::boxed::Box<(dyn Foo + 'static)>` in the current scope
2224
--> $DIR/object-pointer-types.rs:23:7

src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ error[E0599]: no method named `foo` found for struct `A` in the current scope
22
--> $DIR/point-at-arbitrary-self-type-trait-method.rs:9:7
33
|
44
LL | trait B { fn foo(self: Box<Self>); }
5-
| --- the method is available for `std::boxed::Box<A>` here
5+
| ------- --- the method is available for `std::boxed::Box<A>` here
6+
| |
7+
| this trait defines an item `foo`
68
LL | struct A;
79
| --------- method `foo` not found for this
810
...
911
LL | A.foo()
1012
| ^^^ method not found in `A`
1113
|
1214
= help: items from traits can only be used if the trait is implemented and in scope
13-
= note: the following trait defines an item `foo`, perhaps you need to implement it:
14-
candidate #1: `B`
1515

1616
error: aborting due to previous error
1717

src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0599]: no method named `foo_one` found for struct `MyStruct` in the current scope
22
--> $DIR/specialization-trait-not-implemented.rs:22:29
33
|
4+
LL | trait Foo {
5+
| --------- this trait defines an item `foo_one`
6+
...
47
LL | struct MyStruct;
58
| ----------------
69
| |
@@ -13,8 +16,6 @@ LL | println!("{}", MyStruct.foo_one());
1316
= note: the method `foo_one` exists but the following trait bounds were not satisfied:
1417
`MyStruct: Foo`
1518
= help: items from traits can only be used if the trait is implemented and in scope
16-
= note: the following trait defines an item `foo_one`, perhaps you need to implement it:
17-
candidate #1: `Foo`
1819

1920
error: aborting due to previous error
2021

0 commit comments

Comments
 (0)