Skip to content

Commit 5aca6da

Browse files
authored
Rollup merge of rust-lang#84499 - estebank:issue-84272, r=jackh726
Tweak trait not `use`d suggestion Fix rust-lang#84272. Follow up to rust-lang#83667.
2 parents e324a36 + fb1fb7d commit 5aca6da

10 files changed

+96
-8
lines changed

compiler/rustc_typeck/src/check/method/suggest.rs

+29-8
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
988988
let mut alt_rcvr_sugg = false;
989989
if let SelfSource::MethodCall(rcvr) = source {
990990
debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
991+
let skippable = [
992+
self.tcx.lang_items().clone_trait(),
993+
self.tcx.lang_items().deref_trait(),
994+
self.tcx.lang_items().deref_mut_trait(),
995+
self.tcx.lang_items().drop_trait(),
996+
];
991997
// Try alternative arbitrary self types that could fulfill this call.
992998
// FIXME: probe for all types that *could* be arbitrary self-types, not
993999
// just this list.
@@ -996,6 +1002,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9961002
(self.tcx.mk_mut_ref(&ty::ReErased, rcvr_ty), "&mut "),
9971003
(self.tcx.mk_imm_ref(&ty::ReErased, rcvr_ty), "&"),
9981004
] {
1005+
if let Ok(pick) = self.lookup_probe(
1006+
span,
1007+
item_name,
1008+
rcvr_ty,
1009+
rcvr,
1010+
crate::check::method::probe::ProbeScope::AllTraits,
1011+
) {
1012+
// If the method is defined for the receiver we have, it likely wasn't `use`d.
1013+
// We point at the method, but we just skip the rest of the check for arbitrary
1014+
// self types and rely on the suggestion to `use` the trait from
1015+
// `suggest_valid_traits`.
1016+
let did = Some(pick.item.container.id());
1017+
let skip = skippable.contains(&did);
1018+
if pick.autoderefs == 0 && !skip {
1019+
err.span_label(
1020+
pick.item.ident.span,
1021+
&format!("the method is available for `{}` here", rcvr_ty),
1022+
);
1023+
}
1024+
break;
1025+
}
9991026
for (rcvr_ty, pre) in &[
10001027
(self.tcx.mk_lang_item(rcvr_ty, LangItem::OwnedBox), "Box::new"),
10011028
(self.tcx.mk_lang_item(rcvr_ty, LangItem::Pin), "Pin::new"),
@@ -1015,13 +1042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10151042
// We don't want to suggest a container type when the missing
10161043
// method is `.clone()` or `.deref()` otherwise we'd suggest
10171044
// `Arc::new(foo).clone()`, which is far from what the user wants.
1018-
let skip = [
1019-
self.tcx.lang_items().clone_trait(),
1020-
self.tcx.lang_items().deref_trait(),
1021-
self.tcx.lang_items().deref_mut_trait(),
1022-
self.tcx.lang_items().drop_trait(),
1023-
]
1024-
.contains(&did);
1045+
let skip = skippable.contains(&did);
10251046
// Make sure the method is defined for the *actual* receiver: we don't
10261047
// want to treat `Box<Self>` as a receiver if it only works because of
10271048
// an autoderef to `&self`
@@ -1047,7 +1068,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10471068
}
10481069
}
10491070
}
1050-
if !alt_rcvr_sugg && self.suggest_valid_traits(err, valid_out_of_scope_traits) {
1071+
if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
10511072
return;
10521073
}
10531074

src/test/ui/hygiene/trait_items.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0599]: no method named `f` found for unit type `()` in the current scope
22
--> $DIR/trait_items.rs:17:24
33
|
4+
LL | fn f(&self) {}
5+
| - the method is available for `()` here
6+
...
47
LL | fn f() { ::baz::m!(); }
58
| ------------ in this macro invocation
69
...

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

+8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ LL | use no_method_suggested_traits::Reexported;
3737
error[E0599]: no method named `method` found for type `char` in the current scope
3838
--> $DIR/no-method-suggested-traits.rs:30:9
3939
|
40+
LL | fn method(&self) {}
41+
| ------ the method is available for `char` here
42+
...
4043
LL | 'a'.method();
4144
| ^^^^^^ method not found in `char`
4245
|
@@ -63,6 +66,11 @@ error[E0599]: no method named `method` found for type `i32` in the current scope
6366
|
6467
LL | 1i32.method();
6568
| ^^^^^^ method not found in `i32`
69+
|
70+
::: $DIR/auxiliary/no_method_suggested_traits.rs:8:12
71+
|
72+
LL | fn method(&self) {}
73+
| ------ the method is available for `i32` here
6674
|
6775
= help: items from traits can only be used if the trait is in scope
6876
help: the following trait is implemented but not in scope; perhaps add a `use` for it:

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

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0599]: no method named `a` found for unit type `()` in the current scope
33
|
44
LL | ().a();
55
| ^ method not found in `()`
6+
|
7+
::: $DIR/auxiliary/xcrate-issue-43189-a.rs:5:8
8+
|
9+
LL | fn a(&self) {}
10+
| - the method is available for `()` here
611
|
712
= help: items from traits can only be used if the trait is in scope
813
help: the following trait is implemented but not in scope; perhaps add a `use` for it:

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

+10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0599]: no method named `trait_method` found for struct `FooStruct` in the
33
|
44
LL | reexported_trait::FooStruct.trait_method();
55
| ^^^^^^^^^^^^ method not found in `FooStruct`
6+
|
7+
::: $DIR/auxiliary/reexported-trait.rs:3:12
8+
|
9+
LL | fn trait_method(&self) {
10+
| ------------ the method is available for `FooStruct` here
611
|
712
= help: items from traits can only be used if the trait is in scope
813
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
@@ -15,6 +20,11 @@ error[E0599]: no method named `trait_method_b` found for struct `FooStruct` in t
1520
|
1621
LL | reexported_trait::FooStruct.trait_method_b();
1722
| ^^^^^^^^^^^^^^ method not found in `FooStruct`
23+
|
24+
::: $DIR/auxiliary/reexported-trait.rs:7:12
25+
|
26+
LL | fn trait_method_b(&self) {
27+
| -------------- the method is available for `FooStruct` here
1828
|
1929
= help: items from traits can only be used if the trait is in scope
2030
help: the following trait is implemented but not in scope; perhaps add a `use` for it:

src/test/ui/rust-2018/trait-import-suggestions.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0599]: no method named `foobar` found for type `u32` in the current scope
22
--> $DIR/trait-import-suggestions.rs:22:11
33
|
4+
LL | fn foobar(&self) { }
5+
| ------ the method is available for `u32` here
6+
...
47
LL | x.foobar();
58
| ^^^^^^ method not found in `u32`
69
|
@@ -11,6 +14,9 @@ LL | x.foobar();
1114
error[E0599]: no method named `bar` found for type `u32` in the current scope
1215
--> $DIR/trait-import-suggestions.rs:28:7
1316
|
17+
LL | fn bar(&self) { }
18+
| --- the method is available for `u32` here
19+
...
1420
LL | x.bar();
1521
| ^^^ method not found in `u32`
1622
|

src/test/ui/shadowed/shadowed-trait-methods.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0599]: no method named `f` found for unit type `()` in the current scope
22
--> $DIR/shadowed-trait-methods.rs:13:8
33
|
4+
LL | pub trait T { fn f(&self) {} }
5+
| - the method is available for `()` here
6+
...
47
LL | ().f()
58
| ^ method not found in `()`
69
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use std::hash::BuildHasher;
2+
3+
fn next_u64() -> u64 {
4+
let bh = std::collections::hash_map::RandomState::new();
5+
let h = bh.build_hasher();
6+
h.finish() //~ ERROR no method named `finish` found for struct `DefaultHasher`
7+
}
8+
9+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0599]: no method named `finish` found for struct `DefaultHasher` in the current scope
2+
--> $DIR/import-trait-for-method-call.rs:6:7
3+
|
4+
LL | h.finish()
5+
| ^^^^^^ method not found in `DefaultHasher`
6+
|
7+
::: $SRC_DIR/core/src/hash/mod.rs:LL:COL
8+
|
9+
LL | fn finish(&self) -> u64;
10+
| ------ the method is available for `DefaultHasher` here
11+
|
12+
= help: items from traits can only be used if the trait is in scope
13+
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
14+
|
15+
LL | use std::hash::Hasher;
16+
|
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0599`.

src/test/ui/traits/item-privacy.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ error[E0599]: no method named `b` found for struct `S` in the current scope
2020
LL | struct S;
2121
| --------- method `b` not found for this
2222
...
23+
LL | fn b(&self) { }
24+
| - the method is available for `S` here
25+
...
2326
LL | S.b();
2427
| ^ method not found in `S`
2528
|

0 commit comments

Comments
 (0)