From 2dd6dc1f8633e436ba3c4f23e376e60ffd135e68 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Thu, 6 Feb 2025 14:06:15 -0500 Subject: [PATCH] Label mismatched parameters at the def site for foreign functions. --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 12 +++++++++--- .../extern-fn-arg-names.stderr | 2 +- tests/ui/c-variadic/variadic-ffi-1.stderr | 4 ++-- tests/ui/error-codes/E0060.stderr | 2 +- tests/ui/fn/param-mismatch-foreign.rs | 11 +++++++++++ tests/ui/fn/param-mismatch-foreign.stderr | 19 +++++++++++++++++++ tests/ui/mismatched_types/issue-26480.stderr | 2 +- tests/ui/suggestions/suggest-null-ptr.stderr | 8 ++++---- 8 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 tests/ui/fn/param-mismatch-foreign.rs create mode 100644 tests/ui/fn/param-mismatch-foreign.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 5ce9e0556b4c0..77081548d1156 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2641,8 +2641,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Returns the parameters of a function, with their generic parameters if those are the full - /// type of that parameter. Returns `None` if the function has no generics or the body is - /// unavailable (eg is an instrinsic). + /// type of that parameter. + /// + /// Returns `None` if the body is not a named function (e.g. a closure). fn get_hir_param_info( &self, def_id: DefId, @@ -2667,6 +2668,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind: hir::ItemKind::Fn { sig, generics, body, .. }, .. }) => (sig, generics, Some(body), None), + hir::Node::ForeignItem(&hir::ForeignItem { + kind: hir::ForeignItemKind::Fn(sig, params, generics), + .. + }) => (sig, generics, None, Some(params)), _ => return None, }; @@ -2700,7 +2705,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )) } (None, Some(params)) => { - let params = params.get(is_method as usize..)?; + let params = + params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?; debug_assert_eq!(params.len(), fn_inputs.len()); Some(( fn_inputs.zip(params.iter().map(|param| FnParam::Name(param))).collect(), diff --git a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr index 47fbfc98c676a..2aa4983624ce5 100644 --- a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr +++ b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr @@ -14,7 +14,7 @@ note: function defined here --> $DIR/extern-fn-arg-names.rs:2:8 | LL | fn dstfn(src: i32, dst: err); - | ^^^^^ + | ^^^^^ --- help: provide the argument | LL | dstfn(1, /* dst */); diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index 7a54d043356a3..7eca4cb61bc02 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -14,7 +14,7 @@ note: function defined here --> $DIR/variadic-ffi-1.rs:15:8 | LL | fn foo(f: isize, x: u8, ...); - | ^^^ + | ^^^ - - help: provide the arguments | LL | foo(/* isize */, /* u8 */); @@ -30,7 +30,7 @@ note: function defined here --> $DIR/variadic-ffi-1.rs:15:8 | LL | fn foo(f: isize, x: u8, ...); - | ^^^ + | ^^^ - help: provide the argument | LL | foo(1, /* u8 */); diff --git a/tests/ui/error-codes/E0060.stderr b/tests/ui/error-codes/E0060.stderr index 8387b15b97087..aadf1ea93cb8c 100644 --- a/tests/ui/error-codes/E0060.stderr +++ b/tests/ui/error-codes/E0060.stderr @@ -8,7 +8,7 @@ note: function defined here --> $DIR/E0060.rs:2:8 | LL | fn printf(_: *const u8, ...) -> u32; - | ^^^^^^ + | ^^^^^^ - help: provide the argument | LL | unsafe { printf(/* *const u8 */); } diff --git a/tests/ui/fn/param-mismatch-foreign.rs b/tests/ui/fn/param-mismatch-foreign.rs new file mode 100644 index 0000000000000..2ab2bf95448a4 --- /dev/null +++ b/tests/ui/fn/param-mismatch-foreign.rs @@ -0,0 +1,11 @@ +extern "C" { + fn foo(x: i32, y: u32, z: i32); + //~^ NOTE function defined here +} + +fn main() { + foo(1i32, 2i32); + //~^ ERROR this function takes 3 arguments but 2 arguments were supplied + //~| NOTE argument #2 of type `u32` is missing + //~| HELP provide the argument +} diff --git a/tests/ui/fn/param-mismatch-foreign.stderr b/tests/ui/fn/param-mismatch-foreign.stderr new file mode 100644 index 0000000000000..1182908891c62 --- /dev/null +++ b/tests/ui/fn/param-mismatch-foreign.stderr @@ -0,0 +1,19 @@ +error[E0061]: this function takes 3 arguments but 2 arguments were supplied + --> $DIR/param-mismatch-foreign.rs:7:5 + | +LL | foo(1i32, 2i32); + | ^^^ ---- argument #2 of type `u32` is missing + | +note: function defined here + --> $DIR/param-mismatch-foreign.rs:2:8 + | +LL | fn foo(x: i32, y: u32, z: i32); + | ^^^ - +help: provide the argument + | +LL | foo(1i32, /* u32 */, 2i32); + | ~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/mismatched_types/issue-26480.stderr b/tests/ui/mismatched_types/issue-26480.stderr index ae10a00671e61..da8d73225f317 100644 --- a/tests/ui/mismatched_types/issue-26480.stderr +++ b/tests/ui/mismatched_types/issue-26480.stderr @@ -13,7 +13,7 @@ note: function defined here --> $DIR/issue-26480.rs:2:8 | LL | fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64; - | ^^^^^ + | ^^^^^ ----- = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit | diff --git a/tests/ui/suggestions/suggest-null-ptr.stderr b/tests/ui/suggestions/suggest-null-ptr.stderr index 66a79d0749ee8..a811d6d19c722 100644 --- a/tests/ui/suggestions/suggest-null-ptr.stderr +++ b/tests/ui/suggestions/suggest-null-ptr.stderr @@ -12,7 +12,7 @@ note: function defined here --> $DIR/suggest-null-ptr.rs:7:8 | LL | fn foo(ptr: *const u8); - | ^^^ + | ^^^ --- help: if you meant to create a null pointer, use `std::ptr::null()` | LL | foo(std::ptr::null()); @@ -32,7 +32,7 @@ note: function defined here --> $DIR/suggest-null-ptr.rs:9:8 | LL | fn foo_mut(ptr: *mut u8); - | ^^^^^^^ + | ^^^^^^^ --- help: if you meant to create a null pointer, use `std::ptr::null_mut()` | LL | foo_mut(std::ptr::null_mut()); @@ -52,7 +52,7 @@ note: function defined here --> $DIR/suggest-null-ptr.rs:11:8 | LL | fn usize(ptr: *const usize); - | ^^^^^ + | ^^^^^ --- help: if you meant to create a null pointer, use `std::ptr::null()` | LL | usize(std::ptr::null()); @@ -72,7 +72,7 @@ note: function defined here --> $DIR/suggest-null-ptr.rs:13:8 | LL | fn usize_mut(ptr: *mut usize); - | ^^^^^^^^^ + | ^^^^^^^^^ --- help: if you meant to create a null pointer, use `std::ptr::null_mut()` | LL | usize_mut(std::ptr::null_mut());