Skip to content

Commit 13eb0ec

Browse files
committed
Auto merge of #42383 - estebank:candidate-newline, r=arielb1
Use multiline note for trait suggestion
2 parents c94a9ac + 397972f commit 13eb0ec

11 files changed

+426
-169
lines changed

src/librustc_typeck/check/method/suggest.rs

+28-29
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
242242
macro_rules! report_function {
243243
($span:expr, $name:expr) => {
244244
err.note(&format!("{} is a function, perhaps you wish to call it",
245-
$name));
245+
$name));
246246
}
247247
}
248248

@@ -329,9 +329,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
329329
let mut candidates = valid_out_of_scope_traits;
330330
candidates.sort();
331331
candidates.dedup();
332-
let msg = format!("items from traits can only be used if the trait is in scope; the \
333-
following {traits_are} implemented but not in scope, perhaps add \
334-
a `use` for {one_of_them}:",
332+
err.help("items from traits can only be used if the trait is in scope");
333+
let mut msg = format!("the following {traits_are} implemented but not in scope, \
334+
perhaps add a `use` for {one_of_them}:",
335335
traits_are = if candidates.len() == 1 {
336336
"trait is"
337337
} else {
@@ -343,17 +343,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
343343
"one of them"
344344
});
345345

346-
err.help(&msg[..]);
347-
348346
let limit = if candidates.len() == 5 { 5 } else { 4 };
349347
for (i, trait_did) in candidates.iter().take(limit).enumerate() {
350-
err.help(&format!("candidate #{}: `use {};`",
351-
i + 1,
352-
self.tcx.item_path_str(*trait_did)));
348+
msg.push_str(&format!("\ncandidate #{}: `use {};`",
349+
i + 1,
350+
self.tcx.item_path_str(*trait_did)));
353351
}
354352
if candidates.len() > limit {
355-
err.note(&format!("and {} others", candidates.len() - limit));
353+
msg.push_str(&format!("\nand {} others", candidates.len() - limit));
356354
}
355+
err.note(&msg[..]);
356+
357357
return;
358358
}
359359

@@ -383,28 +383,27 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
383383
// FIXME #21673 this help message could be tuned to the case
384384
// of a type parameter: suggest adding a trait bound rather
385385
// than implementing.
386-
let msg = format!("items from traits can only be used if the trait is implemented \
387-
and in scope; the following {traits_define} an item `{name}`, \
388-
perhaps you need to implement {one_of_them}:",
389-
traits_define = if candidates.len() == 1 {
390-
"trait defines"
391-
} else {
392-
"traits define"
393-
},
394-
one_of_them = if candidates.len() == 1 {
395-
"it"
396-
} else {
397-
"one of them"
398-
},
399-
name = item_name);
400-
401-
err.help(&msg[..]);
386+
err.help("items from traits can only be used if the trait is implemented and in scope");
387+
let mut msg = format!("the following {traits_define} an item `{name}`, \
388+
perhaps you need to implement {one_of_them}:",
389+
traits_define = if candidates.len() == 1 {
390+
"trait defines"
391+
} else {
392+
"traits define"
393+
},
394+
one_of_them = if candidates.len() == 1 {
395+
"it"
396+
} else {
397+
"one of them"
398+
},
399+
name = item_name);
402400

403401
for (i, trait_info) in candidates.iter().enumerate() {
404-
err.help(&format!("candidate #{}: `{}`",
405-
i + 1,
406-
self.tcx.item_path_str(trait_info.def_id)));
402+
msg.push_str(&format!("\ncandidate #{}: `{}`",
403+
i + 1,
404+
self.tcx.item_path_str(trait_info.def_id)));
407405
}
406+
err.note(&msg[..]);
408407
}
409408
}
410409

src/test/compile-fail/method-call-err-msg.rs

+1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ fn main() {
3333
y.zero()
3434
.take() //~ ERROR no method named `take` found for type `Foo` in the current scope
3535
//~^ NOTE the method `take` exists but the following trait bounds were not satisfied
36+
//~| NOTE the following traits define an item `take`, perhaps you need to implement one of them
3637
.one(0);
3738
}

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

-134
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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
8+
= note: the following trait defines an item `foo`, perhaps you need to implement it:
9+
candidate #1: `Foo`
10+
11+
error: aborting due to previous error(s)
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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
8+
= note: the following traits define an item `is_empty`, perhaps you need to implement one of them:
9+
candidate #1: `std::iter::ExactSizeIterator`
10+
candidate #2: `core::slice::SliceExt`
11+
candidate #3: `core::str::StrExt`
12+
13+
error: aborting due to previous error(s)
14+
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)