Skip to content

Commit dd3b825

Browse files
committed
Do not suggest pinning missing .get_ref()
When suggesting field access which would encounter a method not found, do not suggest pinning when those methods are on `impl Pin` itself. ``` error[E0599]: no method named `get_ref` found for tuple `(BufReader<File>,)` in the current scope --> $DIR/missing-field-access.rs:11:15 | LL | let x = f.get_ref(); | ^^^^^^^ method not found in `(BufReader<File>,)` | help: one of the expressions' fields has a method of the same name | LL | let x = f.0.get_ref(); | ++ ``` instead of ``` error[E0599]: no method named `get_ref` found for tuple `(BufReader<File>,)` in the current scope --> $DIR/missing-field-access.rs:11:15 | LL | let x = f.get_ref(); | ^^^^^^^ method not found in `(BufReader<File>,)` | help: one of the expressions' fields has a method of the same name | LL | let x = f.0.get_ref(); | ++ help: consider pinning the expression | LL ~ let mut pinned = std::pin::pin!(f); LL ~ let x = pinned.as_ref().get_ref(); | ```
1 parent 26c12c7 commit dd3b825

File tree

3 files changed

+14
-18
lines changed

3 files changed

+14
-18
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3585,6 +3585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35853585
self.tcx.lang_items().deref_trait(),
35863586
self.tcx.lang_items().deref_mut_trait(),
35873587
self.tcx.lang_items().drop_trait(),
3588+
self.tcx.lang_items().pin_type(),
35883589
self.tcx.get_diagnostic_item(sym::AsRef),
35893590
];
35903591
// Try alternative arbitrary self types that could fulfill this call.
@@ -3670,7 +3671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
36703671
)
36713672
{
36723673
debug!("try_alt_rcvr: pick candidate {:?}", pick);
3673-
let did = Some(pick.item.container_id(self.tcx));
3674+
let did = pick.item.trait_container(self.tcx);
36743675
// We don't want to suggest a container type when the missing
36753676
// method is `.clone()` or `.deref()` otherwise we'd suggest
36763677
// `Arc::new(foo).clone()`, which is far from what the user wants.
@@ -3734,6 +3735,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37343735
// We skip some common traits that we don't want to consider because autoderefs
37353736
// would take care of them.
37363737
&& !skippable.contains(&Some(pick.item.container_id(self.tcx)))
3738+
&& !skippable.contains(&pick.item.impl_container(self.tcx).and_then(|did| {
3739+
match self.tcx.type_of(did).instantiate_identity().kind() {
3740+
ty::Adt(def, _) => Some(def.did()),
3741+
_ => None,
3742+
}
3743+
}))
37373744
// We don't want to go through derefs.
37383745
&& pick.autoderefs == 0
37393746
// Check that the method of the same name that was found on the new `Pin<T>`
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// Ensure that suggestions to search for missing intermediary field accesses are available for both
2+
// tuple structs *and* regular tuples.
3+
// Ensure that we do not suggest pinning the expression just because `Pin::get_ref` exists.
4+
// https://github.com/rust-lang/rust/issues/144602
15
use std::{fs::File, io::BufReader};
26

37
struct F(BufReader<File>);
@@ -6,12 +10,7 @@ fn main() {
610
let f = F(BufReader::new(File::open("x").unwrap()));
711
let x = f.get_ref(); //~ ERROR E0599
812
//~^ HELP one of the expressions' fields has a method of the same name
9-
//~| HELP consider pinning the expression
1013
let f = (BufReader::new(File::open("x").unwrap()), );
1114
let x = f.get_ref(); //~ ERROR E0599
1215
//~^ HELP one of the expressions' fields has a method of the same name
13-
//~| HELP consider pinning the expression
14-
15-
// FIXME(estebank): the pinning suggestion should not be included in either case.
16-
// https://github.com/rust-lang/rust/issues/144602
1716
}

tests/ui/tuple/missing-field-access.stderr

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0599]: no method named `get_ref` found for struct `F` in the current scope
2-
--> $DIR/missing-field-access.rs:7:15
2+
--> $DIR/missing-field-access.rs:11:15
33
|
44
LL | struct F(BufReader<File>);
55
| -------- method `get_ref` not found for this struct
@@ -11,14 +11,9 @@ help: one of the expressions' fields has a method of the same name
1111
|
1212
LL | let x = f.0.get_ref();
1313
| ++
14-
help: consider pinning the expression
15-
|
16-
LL ~ let mut pinned = std::pin::pin!(f);
17-
LL ~ let x = pinned.as_ref().get_ref();
18-
|
1914

2015
error[E0599]: no method named `get_ref` found for tuple `(BufReader<File>,)` in the current scope
21-
--> $DIR/missing-field-access.rs:11:15
16+
--> $DIR/missing-field-access.rs:14:15
2217
|
2318
LL | let x = f.get_ref();
2419
| ^^^^^^^ method not found in `(BufReader<File>,)`
@@ -27,11 +22,6 @@ help: one of the expressions' fields has a method of the same name
2722
|
2823
LL | let x = f.0.get_ref();
2924
| ++
30-
help: consider pinning the expression
31-
|
32-
LL ~ let mut pinned = std::pin::pin!(f);
33-
LL ~ let x = pinned.as_ref().get_ref();
34-
|
3525

3626
error: aborting due to 2 previous errors
3727

0 commit comments

Comments
 (0)