about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2025-02-03 19:17:46 -0500
committerJason Newcomb <jsnewcomb@pm.me>2025-02-03 20:55:22 -0500
commit8b1c28fdd0716e16a8d1776b40d2896128dd7654 (patch)
tree3f65c9b89644ecb64b00224f0c3ead4af60cd99b
parent6378fbc366ad552ee791bcac670e0f3939489ef7 (diff)
downloadrust-8b1c28fdd0716e16a8d1776b40d2896128dd7654.tar.gz
rust-8b1c28fdd0716e16a8d1776b40d2896128dd7654.zip
Fix ICE when function argument mismatches.
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs5
-rw-r--r--tests/crashes/135124.rs9
-rw-r--r--tests/ui/fn/error-recovery-mismatch.rs20
-rw-r--r--tests/ui/fn/error-recovery-mismatch.stderr46
4 files changed, 70 insertions, 10 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index e30c0e115dc..e90474cabb4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -126,7 +126,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Err(guar) => Err(guar),
         };
         if let Err(guar) = has_error {
-            let err_inputs = self.err_args(args_no_rcvr.len(), guar);
+            let err_inputs = self.err_args(
+                method.map_or(args_no_rcvr.len(), |method| method.sig.inputs().len() - 1),
+                guar,
+            );
             let err_output = Ty::new_error(self.tcx, guar);
 
             let err_inputs = match tuple_arguments {
diff --git a/tests/crashes/135124.rs b/tests/crashes/135124.rs
deleted file mode 100644
index d6655cb46fa..00000000000
--- a/tests/crashes/135124.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #135124
-trait A  {
-    fn y(&self)
-    {
-        fn call() -> impl Sized {}
-        self.fold(call());
-    }
-    fn fold(&self, &self._) {}
-}
diff --git a/tests/ui/fn/error-recovery-mismatch.rs b/tests/ui/fn/error-recovery-mismatch.rs
new file mode 100644
index 00000000000..a50a30c8c78
--- /dev/null
+++ b/tests/ui/fn/error-recovery-mismatch.rs
@@ -0,0 +1,20 @@
+// Used to ICE due to a size mismatch between the actual fake signature of `fold` and the
+// generated signature used reporting the parameter mismatch at the call site.
+// See issue #135124
+
+trait A  {
+    fn y(&self)
+    {
+        fn call() -> impl Sized {}
+        self.fold(call(), call());
+    }
+    fn fold<T>(&self, _: T, &self._) {}
+    //~^ ERROR unexpected `self` parameter in function
+    //~| ERROR expected one of `)` or `,`, found `.`
+    //~| ERROR identifier `self` is bound more than once in this parameter list
+    //~| WARNING anonymous parameters are deprecated
+    //~| WARNING this is accepted in the current edition
+    //~| ERROR the placeholder `_` is not allowed within types
+}
+
+fn main() {}
diff --git a/tests/ui/fn/error-recovery-mismatch.stderr b/tests/ui/fn/error-recovery-mismatch.stderr
new file mode 100644
index 00000000000..ad4652c11c1
--- /dev/null
+++ b/tests/ui/fn/error-recovery-mismatch.stderr
@@ -0,0 +1,46 @@
+error: unexpected `self` parameter in function
+  --> $DIR/error-recovery-mismatch.rs:11:29
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                             ^^^^^ must be the first parameter of an associated function
+
+error: expected one of `)` or `,`, found `.`
+  --> $DIR/error-recovery-mismatch.rs:11:34
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                                  ^
+   |                                  |
+   |                                  expected one of `)` or `,`
+   |                                  help: missing `,`
+
+error[E0415]: identifier `self` is bound more than once in this parameter list
+  --> $DIR/error-recovery-mismatch.rs:11:30
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                              ^^^^ used as parameter more than once
+
+warning: anonymous parameters are deprecated and will be removed in the next edition
+  --> $DIR/error-recovery-mismatch.rs:11:35
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                                   ^ help: try naming the parameter or explicitly ignoring it: `_: _`
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
+   = note: `#[warn(anonymous_parameters)]` on by default
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/error-recovery-mismatch.rs:11:35
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                                   ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn fold<T, U>(&self, _: T, &self.U) {}
+   |              +++                     ~
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0121, E0415.
+For more information about an error, try `rustc --explain E0121`.