Do not suggest wrapping an item if it has ambiguous un-imported methods
This commit is contained in:
parent
03a8cc7df1
commit
0626919f21
@ -1485,27 +1485,38 @@ fn suggest_traits_to_import(
|
|||||||
(self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
|
(self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
|
||||||
(self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
|
(self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
|
||||||
] {
|
] {
|
||||||
if let Ok(pick) = self.lookup_probe(
|
match self.lookup_probe(
|
||||||
span,
|
span,
|
||||||
item_name,
|
item_name,
|
||||||
*rcvr_ty,
|
*rcvr_ty,
|
||||||
rcvr,
|
rcvr,
|
||||||
crate::check::method::probe::ProbeScope::AllTraits,
|
crate::check::method::probe::ProbeScope::AllTraits,
|
||||||
) {
|
) {
|
||||||
// If the method is defined for the receiver we have, it likely wasn't `use`d.
|
Ok(pick) => {
|
||||||
// We point at the method, but we just skip the rest of the check for arbitrary
|
// If the method is defined for the receiver we have, it likely wasn't `use`d.
|
||||||
// self types and rely on the suggestion to `use` the trait from
|
// We point at the method, but we just skip the rest of the check for arbitrary
|
||||||
// `suggest_valid_traits`.
|
// self types and rely on the suggestion to `use` the trait from
|
||||||
let did = Some(pick.item.container.id());
|
// `suggest_valid_traits`.
|
||||||
let skip = skippable.contains(&did);
|
let did = Some(pick.item.container.id());
|
||||||
if pick.autoderefs == 0 && !skip {
|
let skip = skippable.contains(&did);
|
||||||
err.span_label(
|
if pick.autoderefs == 0 && !skip {
|
||||||
pick.item.ident(self.tcx).span,
|
err.span_label(
|
||||||
&format!("the method is available for `{}` here", rcvr_ty),
|
pick.item.ident(self.tcx).span,
|
||||||
);
|
&format!("the method is available for `{}` here", rcvr_ty),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
Err(MethodError::Ambiguity(_)) => {
|
||||||
|
// If the method is defined (but ambiguous) for the receiver we have, it is also
|
||||||
|
// likely we haven't `use`d it. It may be possible that if we `Box`/`Pin`/etc.
|
||||||
|
// the receiver, then it might disambiguate this method, but I think these
|
||||||
|
// suggestions are generally misleading (see #94218).
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (rcvr_ty, pre) in &[
|
for (rcvr_ty, pre) in &[
|
||||||
(self.tcx.mk_lang_item(*rcvr_ty, LangItem::OwnedBox), "Box::new"),
|
(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_lang_item(*rcvr_ty, LangItem::Pin), "Pin::new"),
|
||||||
|
@ -4,34 +4,8 @@ error[E0599]: no method named `try_into` found for type `u8` in the current scop
|
|||||||
LL | let _: u32 = 3u8.try_into().unwrap();
|
LL | let _: u32 = 3u8.try_into().unwrap();
|
||||||
| ^^^^^^^^ method not found in `u8`
|
| ^^^^^^^^ method not found in `u8`
|
||||||
|
|
|
|
||||||
::: $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
|
||||||
|
|
|
||||||
LL | fn try_into(self) -> Result<T, Self::Error>;
|
|
||||||
| --------
|
|
||||||
| |
|
|
||||||
| the method is available for `Box<u8>` here
|
|
||||||
| the method is available for `Pin<u8>` here
|
|
||||||
| the method is available for `Arc<u8>` here
|
|
||||||
| the method is available for `Rc<u8>` here
|
|
||||||
|
|
|
||||||
= help: items from traits can only be used if the trait is in scope
|
= help: items from traits can only be used if the trait is in scope
|
||||||
= note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
|
= note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
|
||||||
help: consider wrapping the receiver expression with the appropriate type
|
|
||||||
|
|
|
||||||
LL | let _: u32 = Box::new(3u8).try_into().unwrap();
|
|
||||||
| +++++++++ +
|
|
||||||
help: consider wrapping the receiver expression with the appropriate type
|
|
||||||
|
|
|
||||||
LL | let _: u32 = Pin::new(3u8).try_into().unwrap();
|
|
||||||
| +++++++++ +
|
|
||||||
help: consider wrapping the receiver expression with the appropriate type
|
|
||||||
|
|
|
||||||
LL | let _: u32 = Arc::new(3u8).try_into().unwrap();
|
|
||||||
| +++++++++ +
|
|
||||||
help: consider wrapping the receiver expression with the appropriate type
|
|
||||||
|
|
|
||||||
LL | let _: u32 = Rc::new(3u8).try_into().unwrap();
|
|
||||||
| ++++++++ +
|
|
||||||
help: the following traits are implemented but not in scope; perhaps add a `use` for one of them:
|
help: the following traits are implemented but not in scope; perhaps add a `use` for one of them:
|
||||||
|
|
|
|
||||||
LL | use crate::m::TryIntoU32;
|
LL | use crate::m::TryIntoU32;
|
||||||
|
21
src/test/ui/suggestions/dont-wrap-ambiguous-receivers.rs
Normal file
21
src/test/ui/suggestions/dont-wrap-ambiguous-receivers.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
mod banana {
|
||||||
|
//~^ HELP the following traits are implemented but not in scope
|
||||||
|
pub struct Chaenomeles;
|
||||||
|
|
||||||
|
pub trait Apple {
|
||||||
|
fn pick(&self) {}
|
||||||
|
}
|
||||||
|
impl Apple for Chaenomeles {}
|
||||||
|
|
||||||
|
pub trait Peach {
|
||||||
|
fn pick(&self, a: &mut ()) {}
|
||||||
|
}
|
||||||
|
impl<Mango: Peach> Peach for Box<Mango> {}
|
||||||
|
impl Peach for Chaenomeles {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
banana::Chaenomeles.pick()
|
||||||
|
//~^ ERROR no method named
|
||||||
|
//~| HELP items from traits can only be used if the trait is in scope
|
||||||
|
}
|
20
src/test/ui/suggestions/dont-wrap-ambiguous-receivers.stderr
Normal file
20
src/test/ui/suggestions/dont-wrap-ambiguous-receivers.stderr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
error[E0599]: no method named `pick` found for struct `Chaenomeles` in the current scope
|
||||||
|
--> $DIR/dont-wrap-ambiguous-receivers.rs:18:25
|
||||||
|
|
|
||||||
|
LL | pub struct Chaenomeles;
|
||||||
|
| ----------------------- method `pick` not found for this
|
||||||
|
...
|
||||||
|
LL | banana::Chaenomeles.pick()
|
||||||
|
| ^^^^ method not found in `Chaenomeles`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the trait is in scope
|
||||||
|
help: the following traits are implemented but not in scope; perhaps add a `use` for one of them:
|
||||||
|
|
|
||||||
|
LL | use banana::Apple;
|
||||||
|
|
|
||||||
|
LL | use banana::Peach;
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Reference in New Issue
Block a user