mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-06 20:13:42 +00:00
Suggest Pin/Box/Arc for more cases
This commit is contained in:
parent
16143d1067
commit
d326c218ef
@ -987,59 +987,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
) {
|
) {
|
||||||
let mut alt_rcvr_sugg = false;
|
let mut alt_rcvr_sugg = false;
|
||||||
if let SelfSource::MethodCall(rcvr) = source {
|
if let SelfSource::MethodCall(rcvr) = source {
|
||||||
info!(?span, ?item_name, ?rcvr_ty, ?rcvr);
|
debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
|
||||||
if let ty::Adt(..) = rcvr_ty.kind() {
|
// Try alternative arbitrary self types that could fulfill this call.
|
||||||
// Try alternative arbitrary self types that could fulfill this call.
|
// 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) in &[
|
||||||
for (rcvr_ty, post) in &[
|
(rcvr_ty, ""),
|
||||||
(rcvr_ty, ""),
|
(self.tcx.mk_mut_ref(&ty::ReErased, rcvr_ty), "&mut "),
|
||||||
(self.tcx.mk_mut_ref(&ty::ReErased, rcvr_ty), "&mut "),
|
(self.tcx.mk_imm_ref(&ty::ReErased, rcvr_ty), "&"),
|
||||||
(self.tcx.mk_imm_ref(&ty::ReErased, rcvr_ty), "&"),
|
] {
|
||||||
|
for (rcvr_ty, pre) in &[
|
||||||
|
(self.tcx.mk_lang_item(rcvr_ty, LangItem::OwnedBox), "Box::new"),
|
||||||
|
(self.tcx.mk_lang_item(rcvr_ty, LangItem::Pin), "Pin::new"),
|
||||||
|
(self.tcx.mk_diagnostic_item(rcvr_ty, sym::Arc), "Arc::new"),
|
||||||
|
(self.tcx.mk_diagnostic_item(rcvr_ty, sym::Rc), "Rc::new"),
|
||||||
] {
|
] {
|
||||||
for (rcvr_ty, pre) in &[
|
if let Some(new_rcvr_t) = *rcvr_ty {
|
||||||
(self.tcx.mk_lang_item(rcvr_ty, LangItem::OwnedBox), "Box::new"),
|
if let Ok(pick) = self.lookup_probe(
|
||||||
(self.tcx.mk_lang_item(rcvr_ty, LangItem::Pin), "Pin::new"),
|
span,
|
||||||
(self.tcx.mk_diagnostic_item(rcvr_ty, sym::Arc), "Arc::new"),
|
item_name,
|
||||||
(self.tcx.mk_diagnostic_item(rcvr_ty, sym::Rc), "Rc::new"),
|
new_rcvr_t,
|
||||||
] {
|
rcvr,
|
||||||
if let Some(new_rcvr_t) = *rcvr_ty {
|
crate::check::method::probe::ProbeScope::AllTraits,
|
||||||
if let Ok(pick) = self.lookup_probe(
|
) {
|
||||||
span,
|
debug!("try_alt_rcvr: pick candidate {:?}", pick);
|
||||||
item_name,
|
let did = Some(pick.item.container.id());
|
||||||
new_rcvr_t,
|
// We don't want to suggest a container type when the missing
|
||||||
rcvr,
|
// method is `.clone()` or `.deref()` otherwise we'd suggest
|
||||||
crate::check::method::probe::ProbeScope::AllTraits,
|
// `Arc::new(foo).clone()`, which is far from what the user wants.
|
||||||
) {
|
let skip = [
|
||||||
debug!("try_alt_rcvr: pick candidate {:?}", pick);
|
self.tcx.lang_items().clone_trait(),
|
||||||
// Make sure the method is defined for the *actual* receiver:
|
self.tcx.lang_items().deref_trait(),
|
||||||
// we don't want to treat `Box<Self>` as a receiver if
|
self.tcx.lang_items().deref_mut_trait(),
|
||||||
// it only works because of an autoderef to `&self`
|
self.tcx.lang_items().drop_trait(),
|
||||||
if pick.autoderefs == 0
|
]
|
||||||
// We don't want to suggest a container type when the missing method is
|
.contains(&did);
|
||||||
// `.clone()`, otherwise we'd suggest `Arc::new(foo).clone()`, which is
|
// Make sure the method is defined for the *actual* receiver: we don't
|
||||||
// far from what the user really wants.
|
// want to treat `Box<Self>` as a receiver if it only works because of
|
||||||
&& Some(pick.item.container.id()) != self.tcx.lang_items().clone_trait()
|
// an autoderef to `&self`
|
||||||
{
|
if pick.autoderefs == 0 && !skip {
|
||||||
err.span_label(
|
err.span_label(
|
||||||
pick.item.ident.span,
|
pick.item.ident.span,
|
||||||
&format!(
|
&format!("the method is available for `{}` here", new_rcvr_t),
|
||||||
"the method is available for `{}` here",
|
);
|
||||||
new_rcvr_t
|
err.multipart_suggestion(
|
||||||
),
|
"consider wrapping the receiver expression with the \
|
||||||
);
|
appropriate type",
|
||||||
err.multipart_suggestion(
|
vec![
|
||||||
"consider wrapping the receiver expression with the \
|
(rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
|
||||||
appropriate type",
|
(rcvr.span.shrink_to_hi(), ")".to_string()),
|
||||||
vec![
|
],
|
||||||
(rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
|
Applicability::MaybeIncorrect,
|
||||||
(rcvr.span.shrink_to_hi(), ")".to_string()),
|
);
|
||||||
],
|
// We don't care about the other suggestions.
|
||||||
Applicability::MaybeIncorrect,
|
alt_rcvr_sugg = true;
|
||||||
);
|
|
||||||
// We don't care about the other suggestions.
|
|
||||||
alt_rcvr_sugg = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user