about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAaron Hill <aa1ronham@gmail.com>2020-06-15 15:15:35 -0400
committerAaron Hill <aa1ronham@gmail.com>2020-06-15 15:15:35 -0400
commit8956a7f58194b5a3a8de944ea1dc1b3b44a070ac (patch)
tree293fd67ec60f187aa97c4856e513e399e0045575
parentff4a2533a0720f9cdd86e02eafa3725f07aa7752 (diff)
downloadrust-8956a7f58194b5a3a8de944ea1dc1b3b44a070ac.tar.gz
rust-8956a7f58194b5a3a8de944ea1dc1b3b44a070ac.zip
Only display other method receiver candidates if they actually apply
Previously, we would suggest `Box<Self>` as a valid receiver, even if
method resolution only succeeded due to an autoderef (e.g. to `&self`)
-rw-r--r--src/librustc_typeck/check/expr.rs14
-rw-r--r--src/test/ui/impl-trait/no-method-suggested-traits.stderr18
-rw-r--r--src/test/ui/traits/trait-item-privacy.stderr7
3 files changed, 10 insertions, 29 deletions
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index bc3ef73d851..e16abed644c 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -913,10 +913,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     rcvr,
                     probe::ProbeScope::AllTraits,
                 ) {
-                    err.span_label(
-                        pick.item.ident.span,
-                        &format!("the method is available for `{}` here", new_rcvr_t),
-                    );
+                    debug!("try_alt_rcvr: pick candidate {:?}", pick);
+                    // Make sure the method is defined for the *actual* receiver:
+                    // we don't want to treat `Box<Self>` as a receiver if
+                    // it only works because of an autoderef to `&self`
+                    if pick.autoderefs == 0 {
+                        err.span_label(
+                            pick.item.ident.span,
+                            &format!("the method is available for `{}` here", new_rcvr_t),
+                        );
+                    }
                 }
             }
         };
diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
index b5135b53e18..3cd4d0dd391 100644
--- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr
+++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
@@ -49,14 +49,6 @@ LL | use foo::Bar;
 error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope
   --> $DIR/no-method-suggested-traits.rs:32:43
    |
-LL |         fn method(&self) {}
-   |            ------
-   |            |
-   |            the method is available for `std::boxed::Box<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
-   |            the method is available for `std::pin::Pin<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
-   |            the method is available for `std::sync::Arc<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
-   |            the method is available for `std::rc::Rc<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
-...
 LL |     std::rc::Rc::new(&mut Box::new(&'a')).method();
    |                                           ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&char>>`
    |
@@ -83,16 +75,6 @@ error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::b
    |
 LL |     std::rc::Rc::new(&mut Box::new(&1i32)).method();
    |                                            ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&i32>>`
-   | 
-  ::: $DIR/auxiliary/no_method_suggested_traits.rs:8:12
-   |
-LL |         fn method(&self) {}
-   |            ------
-   |            |
-   |            the method is available for `std::boxed::Box<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
-   |            the method is available for `std::pin::Pin<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
-   |            the method is available for `std::sync::Arc<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
-   |            the method is available for `std::rc::Rc<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope; perhaps add a `use` for it:
diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr
index 7fd5c11fcf0..3be4f110973 100644
--- a/src/test/ui/traits/trait-item-privacy.stderr
+++ b/src/test/ui/traits/trait-item-privacy.stderr
@@ -20,13 +20,6 @@ error[E0599]: no method named `b` found for struct `S` in the current scope
 LL | struct S;
    | --------- method `b` not found for this
 ...
-LL |         fn b(&self) { }
-   |            -
-   |            |
-   |            the method is available for `std::boxed::Box<S>` here
-   |            the method is available for `std::sync::Arc<S>` here
-   |            the method is available for `std::rc::Rc<S>` here
-...
 LL |     S.b();
    |       ^ method not found in `S`
    |