Skip to content

Commit e935acf

Browse files
committed
Use multiline note for trait suggestion
1 parent 4ed2eda commit e935acf

10 files changed

+401
-167
lines changed

src/librustc_typeck/check/method/suggest.rs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
228228
macro_rules! report_function {
229229
($span:expr, $name:expr) => {
230230
err.note(&format!("{} is a function, perhaps you wish to call it",
231-
$name));
231+
$name));
232232
}
233233
}
234234

@@ -315,9 +315,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
315315
let mut candidates = valid_out_of_scope_traits;
316316
candidates.sort();
317317
candidates.dedup();
318-
let msg = format!("items from traits can only be used if the trait is in scope; the \
319-
following {traits_are} implemented but not in scope, perhaps add \
320-
a `use` for {one_of_them}:",
318+
let mut msg = format!("items from traits can only be used if the trait is in scope; \
319+
the following {traits_are} implemented but not in scope, \
320+
perhaps add a `use` for {one_of_them}:",
321321
traits_are = if candidates.len() == 1 {
322322
"trait is"
323323
} else {
@@ -329,17 +329,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
329329
"one of them"
330330
});
331331

332-
err.help(&msg[..]);
333-
334332
let limit = if candidates.len() == 5 { 5 } else { 4 };
335333
for (i, trait_did) in candidates.iter().take(limit).enumerate() {
336-
err.help(&format!("candidate #{}: `use {};`",
337-
i + 1,
338-
self.tcx.item_path_str(*trait_did)));
334+
msg.push_str(&format!("\ncandidate #{}: `use {};`",
335+
i + 1,
336+
self.tcx.item_path_str(*trait_did)));
339337
}
340338
if candidates.len() > limit {
341-
err.note(&format!("and {} others", candidates.len() - limit));
339+
msg.push_str(&format!("\nand {} others", candidates.len() - limit));
342340
}
341+
err.help(&msg[..]);
342+
343343
return;
344344
}
345345

@@ -369,28 +369,27 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
369369
// FIXME #21673 this help message could be tuned to the case
370370
// of a type parameter: suggest adding a trait bound rather
371371
// than implementing.
372-
let msg = format!("items from traits can only be used if the trait is implemented \
373-
and in scope; the following {traits_define} an item `{name}`, \
374-
perhaps you need to implement {one_of_them}:",
375-
traits_define = if candidates.len() == 1 {
376-
"trait defines"
377-
} else {
378-
"traits define"
379-
},
380-
one_of_them = if candidates.len() == 1 {
381-
"it"
382-
} else {
383-
"one of them"
384-
},
385-
name = item_name);
386-
387-
err.help(&msg[..]);
372+
let mut msg = format!("items from traits can only be used if the trait is implemented \
373+
and in scope; the following {traits_define} an item `{name}`, \
374+
perhaps you need to implement {one_of_them}:",
375+
traits_define = if candidates.len() == 1 {
376+
"trait defines"
377+
} else {
378+
"traits define"
379+
},
380+
one_of_them = if candidates.len() == 1 {
381+
"it"
382+
} else {
383+
"one of them"
384+
},
385+
name = item_name);
388386

389387
for (i, trait_info) in candidates.iter().enumerate() {
390-
err.help(&format!("candidate #{}: `{}`",
391-
i + 1,
392-
self.tcx.item_path_str(trait_info.def_id)));
388+
msg.push_str(&format!("\ncandidate #{}: `{}`",
389+
i + 1,
390+
self.tcx.item_path_str(trait_info.def_id)));
393391
}
392+
err.help(&msg[..]);
394393
}
395394
}
396395

src/test/compile-fail/no-method-suggested-traits.rs

Lines changed: 0 additions & 134 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0599]: no method named `foo` found for type `Bar` in the current scope
2+
--> $DIR/issue-21659-show-relevant-trait-impls-3.rs:30:8
3+
|
4+
30 | f1.foo(1usize);
5+
| ^^^
6+
|
7+
= help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `foo`, perhaps you need to implement it:
8+
candidate #1: `Foo`
9+
10+
error: aborting due to previous error(s)
11+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0599]: no method named `is_empty` found for type `Foo` in the current scope
2+
--> $DIR/method-suggestion-no-duplication.rs:19:15
3+
|
4+
19 | foo(|s| s.is_empty());
5+
| ^^^^^^^^
6+
|
7+
= help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `is_empty`, perhaps you need to implement one of them:
8+
candidate #1: `std::iter::ExactSizeIterator`
9+
candidate #2: `core::slice::SliceExt`
10+
candidate #3: `core::str::StrExt`
11+
12+
error: aborting due to previous error(s)
13+
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:no_method_suggested_traits.rs
12+
extern crate no_method_suggested_traits;
13+
14+
struct Foo;
15+
enum Bar { X }
16+
17+
mod foo {
18+
pub trait Bar {
19+
fn method(&self) {}
20+
21+
fn method2(&self) {}
22+
}
23+
24+
impl Bar for u32 {}
25+
26+
impl Bar for char {}
27+
}
28+
29+
fn main() {
30+
// test the values themselves, and autoderef.
31+
32+
33+
1u32.method();
34+
//~^ HELP following traits are implemented but not in scope, perhaps add a `use` for one of them
35+
//~| ERROR no method named
36+
//~| HELP `use foo::Bar;`
37+
//~| HELP `use no_method_suggested_traits::foo::PubPub;`
38+
std::rc::Rc::new(&mut Box::new(&1u32)).method();
39+
//~^ HELP following traits are implemented but not in scope, perhaps add a `use` for one of them
40+
//~| ERROR no method named
41+
//~| HELP `use foo::Bar;`
42+
//~| HELP `use no_method_suggested_traits::foo::PubPub;`
43+
44+
'a'.method();
45+
//~^ ERROR no method named
46+
//~| HELP the following trait is implemented but not in scope, perhaps add a `use` for it:
47+
//~| HELP `use foo::Bar;`
48+
std::rc::Rc::new(&mut Box::new(&'a')).method();
49+
//~^ ERROR no method named
50+
//~| HELP the following trait is implemented but not in scope, perhaps add a `use` for it:
51+
//~| HELP `use foo::Bar;`
52+
53+
1i32.method();
54+
//~^ ERROR no method named
55+
//~| HELP the following trait is implemented but not in scope, perhaps add a `use` for it:
56+
//~| HELP `use no_method_suggested_traits::foo::PubPub;`
57+
std::rc::Rc::new(&mut Box::new(&1i32)).method();
58+
//~^ ERROR no method named
59+
//~| HELP the following trait is implemented but not in scope, perhaps add a `use` for it:
60+
//~| HELP `use no_method_suggested_traits::foo::PubPub;`
61+
62+
Foo.method();
63+
//~^ ERROR no method named
64+
//~| HELP following traits define an item `method`, perhaps you need to implement one of them
65+
//~| HELP `foo::Bar`
66+
//~| HELP `no_method_suggested_traits::foo::PubPub`
67+
//~| HELP `no_method_suggested_traits::Reexported`
68+
//~| HELP `no_method_suggested_traits::bar::PubPriv`
69+
//~| HELP `no_method_suggested_traits::qux::PrivPub`
70+
//~| HELP `no_method_suggested_traits::quz::PrivPriv`
71+
std::rc::Rc::new(&mut Box::new(&Foo)).method();
72+
//~^ ERROR no method named
73+
//~| HELP following traits define an item `method`, perhaps you need to implement one of them
74+
//~| HELP `foo::Bar`
75+
//~| HELP `no_method_suggested_traits::foo::PubPub`
76+
//~| HELP `no_method_suggested_traits::Reexported`
77+
//~| HELP `no_method_suggested_traits::bar::PubPriv`
78+
//~| HELP `no_method_suggested_traits::qux::PrivPub`
79+
//~| HELP `no_method_suggested_traits::quz::PrivPriv`
80+
81+
1u64.method2();
82+
//~^ ERROR no method named
83+
//~| HELP the following trait defines an item `method2`, perhaps you need to implement it
84+
//~| HELP `foo::Bar`
85+
std::rc::Rc::new(&mut Box::new(&1u64)).method2();
86+
//~^ ERROR no method named
87+
//~| HELP the following trait defines an item `method2`, perhaps you need to implement it
88+
//~| HELP `foo::Bar`
89+
90+
no_method_suggested_traits::Foo.method2();
91+
//~^ ERROR no method named
92+
//~| HELP following trait defines an item `method2`, perhaps you need to implement it
93+
//~| HELP `foo::Bar`
94+
std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2();
95+
//~^ ERROR no method named
96+
//~| HELP following trait defines an item `method2`, perhaps you need to implement it
97+
//~| HELP `foo::Bar`
98+
no_method_suggested_traits::Bar::X.method2();
99+
//~^ ERROR no method named
100+
//~| HELP following trait defines an item `method2`, perhaps you need to implement it
101+
//~| HELP `foo::Bar`
102+
std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2();
103+
//~^ ERROR no method named
104+
//~| HELP following trait defines an item `method2`, perhaps you need to implement it
105+
//~| HELP `foo::Bar`
106+
107+
Foo.method3();
108+
//~^ ERROR no method named
109+
//~| HELP following trait defines an item `method3`, perhaps you need to implement it
110+
//~| HELP `no_method_suggested_traits::foo::PubPub`
111+
std::rc::Rc::new(&mut Box::new(&Foo)).method3();
112+
//~^ ERROR no method named
113+
//~| HELP following trait defines an item `method3`, perhaps you need to implement it
114+
//~| HELP `no_method_suggested_traits::foo::PubPub`
115+
Bar::X.method3();
116+
//~^ ERROR no method named
117+
//~| HELP following trait defines an item `method3`, perhaps you need to implement it
118+
//~| HELP `no_method_suggested_traits::foo::PubPub`
119+
std::rc::Rc::new(&mut Box::new(&Bar::X)).method3();
120+
//~^ ERROR no method named
121+
//~| HELP following trait defines an item `method3`, perhaps you need to implement it
122+
//~| HELP `no_method_suggested_traits::foo::PubPub`
123+
124+
// should have no help:
125+
1_usize.method3(); //~ ERROR no method named
126+
std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); //~ ERROR no method named
127+
no_method_suggested_traits::Foo.method3(); //~ ERROR no method named
128+
std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3();
129+
//~^ ERROR no method named
130+
no_method_suggested_traits::Bar::X.method3(); //~ ERROR no method named
131+
std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3();
132+
//~^ ERROR no method named
133+
}

0 commit comments

Comments
 (0)