From e2151497bfb65945102619e019adb677b2f3ed31 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 28 Oct 2021 00:05:38 +0300 Subject: [PATCH 1/2] Skip suggestions for the AsRef trait --- .../rustc_typeck/src/check/method/suggest.rs | 1 + src/test/ui/typeck/issue-89806.rs | 3 +++ src/test/ui/typeck/issue-89806.stderr | 26 +++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 src/test/ui/typeck/issue-89806.rs create mode 100644 src/test/ui/typeck/issue-89806.stderr diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 28b19981c2d40..934b83bd700e1 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1251,6 +1251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.lang_items().deref_trait(), self.tcx.lang_items().deref_mut_trait(), self.tcx.lang_items().drop_trait(), + self.tcx.get_diagnostic_item(sym::AsRef), ]; // Try alternative arbitrary self types that could fulfill this call. // FIXME: probe for all types that *could* be arbitrary self-types, not diff --git a/src/test/ui/typeck/issue-89806.rs b/src/test/ui/typeck/issue-89806.rs new file mode 100644 index 0000000000000..69cec08652ae9 --- /dev/null +++ b/src/test/ui/typeck/issue-89806.rs @@ -0,0 +1,3 @@ +fn main() { + 0u8.as_ref(); //~ ERROR no method named `as_ref` found for type `u8` in the current scope +} diff --git a/src/test/ui/typeck/issue-89806.stderr b/src/test/ui/typeck/issue-89806.stderr new file mode 100644 index 0000000000000..9a54fac526159 --- /dev/null +++ b/src/test/ui/typeck/issue-89806.stderr @@ -0,0 +1,26 @@ +error[E0599]: no method named `as_ref` found for type `u8` in the current scope + --> $DIR/issue-89806.rs:2:9 + | +LL | 0u8.as_ref(); + | ^^^^^^ method not found in `u8` + | + ::: $SRC_DIR/core/src/pin.rs:LL:COL + | +LL | pub fn as_ref(&self) -> Pin<&P::Target> { + | ------ + | | + | the method is available for `Pin<&mut u8>` here + | the method is available for `Pin<&u8>` here + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Pin::new(&mut 0u8).as_ref(); + | +++++++++++++ + +help: consider wrapping the receiver expression with the appropriate type + | +LL | Pin::new(&0u8).as_ref(); + | ++++++++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. From cad2d21cb669b21b6a31edc0c60b2d0748f3a4f2 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 29 Oct 2021 15:43:33 +0300 Subject: [PATCH 2/2] Explicitly skipping suggestions for 'Pin' as it does not implement the 'AsRef' trait --- .../rustc_typeck/src/check/method/suggest.rs | 8 ++++++-- src/test/ui/typeck/issue-89806.stderr | 17 ----------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 934b83bd700e1..8007b9f23776a 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::print::with_crate_prefix; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_span::lev_distance; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{source_map, FileName, MultiSpan, Span}; +use rustc_span::{source_map, FileName, MultiSpan, Span, Symbol}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{FulfillmentError, Obligation}; @@ -1301,7 +1301,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We don't want to suggest a container type when the missing // method is `.clone()` or `.deref()` otherwise we'd suggest // `Arc::new(foo).clone()`, which is far from what the user wants. - let skip = skippable.contains(&did); + // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not + // implement the `AsRef` trait. + let skip = skippable.contains(&did) + || (("Pin::new" == *pre) + && (Symbol::intern("as_ref") == item_name.name)); // Make sure the method is defined for the *actual* receiver: we don't // want to treat `Box` as a receiver if it only works because of // an autoderef to `&self` diff --git a/src/test/ui/typeck/issue-89806.stderr b/src/test/ui/typeck/issue-89806.stderr index 9a54fac526159..c36b4967ee996 100644 --- a/src/test/ui/typeck/issue-89806.stderr +++ b/src/test/ui/typeck/issue-89806.stderr @@ -3,23 +3,6 @@ error[E0599]: no method named `as_ref` found for type `u8` in the current scope | LL | 0u8.as_ref(); | ^^^^^^ method not found in `u8` - | - ::: $SRC_DIR/core/src/pin.rs:LL:COL - | -LL | pub fn as_ref(&self) -> Pin<&P::Target> { - | ------ - | | - | the method is available for `Pin<&mut u8>` here - | the method is available for `Pin<&u8>` here - | -help: consider wrapping the receiver expression with the appropriate type - | -LL | Pin::new(&mut 0u8).as_ref(); - | +++++++++++++ + -help: consider wrapping the receiver expression with the appropriate type - | -LL | Pin::new(&0u8).as_ref(); - | ++++++++++ + error: aborting due to previous error