about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2022-06-25 15:46:47 -0700
committerMichael Howell <michael@notriddle.com>2022-06-25 15:50:00 -0700
commit0ea59f3bd69b78e4d3812452a0df401662d28fb6 (patch)
treeb75fec139d7de236f3a001d48920177e3d8e7672
parent9cf699d2ff4ff23a6d6862a35727f4d5d3567dae (diff)
diagnostics: consider parameter count when suggesting smart pointers
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs5
-rw-r--r--src/test/ui/suggestions/dont-suggest-pin-array-dot-set.rs15
-rw-r--r--src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr9
3 files changed, 28 insertions, 1 deletions
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 5684979eab7..79a13ce2fca 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -994,6 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         span,
                         rcvr_ty,
                         item_name,
+                        args.map(|args| args.len()),
                         source,
                         out_of_scope_traits,
                         &unsatisfied_predicates,
@@ -1732,6 +1733,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         rcvr_ty: Ty<'tcx>,
         item_name: Ident,
+        inputs_len: Option<usize>,
         source: SelfSource<'tcx>,
         valid_out_of_scope_traits: Vec<DefId>,
         unsatisfied_predicates: &[(
@@ -1808,7 +1810,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
                         // implement the `AsRef` trait.
                         let skip = skippable.contains(&did)
-                            || (("Pin::new" == *pre) && (sym::as_ref == item_name.name));
+                            || (("Pin::new" == *pre) && (sym::as_ref == item_name.name))
+                            || inputs_len.map_or(false, |inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().inputs().len() != inputs_len);
                         // 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`
diff --git a/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.rs b/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.rs
new file mode 100644
index 00000000000..acb897571d6
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.rs
@@ -0,0 +1,15 @@
+// https://github.com/rust-lang/rust/issues/96834
+//
+// This test case verifies that rustc does not make an unhelpful suggestion:
+//
+//     help: consider wrapping the receiver expression with the appropriate type
+//         |
+//     14  |     Pin::new(&mut a).set(0, 3);
+//         |     +++++++++++++  +
+//
+// We can tell that it isn't helpful, because `Pin::set` takes two parameters (including
+// the receiver), but the function call on line 14 supplies three.
+fn main() {
+    let mut a = [0u8; 1];
+    a.set(0, 3); //~ERROR
+}
diff --git a/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr b/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr
new file mode 100644
index 00000000000..677aa031bf7
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-pin-array-dot-set.stderr
@@ -0,0 +1,9 @@
+error[E0599]: no method named `set` found for array `[u8; 1]` in the current scope
+  --> $DIR/dont-suggest-pin-array-dot-set.rs:14:7
+   |
+LL |     a.set(0, 3);
+   |       ^^^ help: there is an associated function with a similar name: `get`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.