rebase and review comments

This commit is contained in:
Esteban Küber 2023-08-14 21:40:11 +00:00
parent 2c3fd1a23a
commit 6b58fbfd7e
3 changed files with 25 additions and 12 deletions

View File

@ -2496,13 +2496,17 @@ fn suggest_traits_to_import(
// FIXME: probe for all types that *could* be arbitrary self-types, not // FIXME: probe for all types that *could* be arbitrary self-types, not
// just this list. // just this list.
for (rcvr_ty, post, pin_call) in &[ for (rcvr_ty, post, pin_call) in &[
(rcvr_ty, "", ""), (rcvr_ty, "", None),
( (
Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty), Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty),
"&mut ", "&mut ",
"as_mut", Some("as_mut"),
),
(
Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty),
"&",
Some("as_ref"),
), ),
(Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty), "&", "as_ref"),
] { ] {
match self.lookup_probe_for_diagnostic( match self.lookup_probe_for_diagnostic(
item_name, item_name,
@ -2594,13 +2598,18 @@ fn suggest_traits_to_import(
} }
} }
} }
// We special case the situation where `Pin::new` wouldn't work, and isntead // We special case the situation where `Pin::new` wouldn't work, and instead
// suggest using the `pin!()` macro instead. // suggest using the `pin!()` macro instead.
if let Some(new_rcvr_t) = Ty::new_lang_item(self.tcx, *rcvr_ty, LangItem::Pin) if let Some(new_rcvr_t) = Ty::new_lang_item(self.tcx, *rcvr_ty, LangItem::Pin)
// We didn't find an alternative receiver for the method.
&& !alt_rcvr_sugg && !alt_rcvr_sugg
// `T: !Unpin`
&& !unpin && !unpin
// The method isn't `as_ref`, as it would provide a wrong suggestion for `Pin`.
&& sym::as_ref != item_name.name && sym::as_ref != item_name.name
&& *pin_call != "" // Either `Pin::as_ref` or `Pin::as_mut`.
&& let Some(pin_call) = pin_call
// Search for `item_name` as a method accessible on `Pin<T>`.
&& let Ok(pick) = self.lookup_probe_for_diagnostic( && let Ok(pick) = self.lookup_probe_for_diagnostic(
item_name, item_name,
new_rcvr_t, new_rcvr_t,
@ -2608,8 +2617,13 @@ fn suggest_traits_to_import(
ProbeScope::AllTraits, ProbeScope::AllTraits,
return_type, return_type,
) )
// We skip some common traits that we don't want to consider because autoderefs
// would take care of them.
&& !skippable.contains(&Some(pick.item.container_id(self.tcx))) && !skippable.contains(&Some(pick.item.container_id(self.tcx)))
// We don't want to go through derefs.
&& pick.autoderefs == 0 && pick.autoderefs == 0
// Check that the method of the same name that was found on the new `Pin<T>`
// receiver has the same number of arguments that appear in the user's code.
&& inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() == inputs_len) && inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() == inputs_len)
{ {
let indent = self.tcx.sess let indent = self.tcx.sess

View File

@ -8,5 +8,6 @@ impl S {
} }
fn main() { fn main() {
Pin::new(&mut S).x(); //~ ERROR no method named `x` found let mut pinned = std::pin::pin!(S);
pinned.as_mut().x(); //~ ERROR no method named `x` found
} }

View File

@ -4,16 +4,14 @@ error[E0599]: no method named `x` found for struct `S` in the current scope
LL | struct S; LL | struct S;
| -------- method `x` not found for this struct | -------- method `x` not found for this struct
... ...
LL | fn x(self: Pin<&mut Self>) {
| - the method is available for `Pin<&mut S>` here
...
LL | S.x(); LL | S.x();
| ^ method not found in `S` | ^ method not found in `S`
| |
help: consider wrapping the receiver expression with the appropriate type help: consider pinning the expression
|
LL ~ let mut pinned = std::pin::pin!(S);
LL ~ pinned.as_mut().x();
| |
LL | Pin::new(&mut S).x();
| +++++++++++++ +
error: aborting due to previous error error: aborting due to previous error