mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #130437 - jder:issue-130372, r=compiler-errors
Avoid crashing on variadic functions when producing arg-mismatch errors Fixes #130372 by accommodating how variadic functions change the argument list length between HIR body and FnDecls. Also degrades the zip_eq to a debug_assert! to match other asserts in the area to avoid being disruptive to users. There is at least one other crash in this area I am working on in #130400 and also considering how we might refactor some of this code to hoist some of this logic up higher. r? `@compiler-errors`
This commit is contained in:
commit
14ee69c250
@ -2619,9 +2619,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
is_method: bool,
|
||||
) -> Option<Vec<(Option<&hir::GenericParam<'_>>, &hir::Param<'_>)>> {
|
||||
let fn_node = self.tcx.hir().get_if_local(def_id)?;
|
||||
let fn_decl = fn_node.fn_decl()?;
|
||||
|
||||
let generic_params: Vec<Option<&hir::GenericParam<'_>>> = fn_node
|
||||
.fn_decl()?
|
||||
let generic_params: Vec<Option<&hir::GenericParam<'_>>> = fn_decl
|
||||
.inputs
|
||||
.into_iter()
|
||||
.skip(if is_method { 1 } else { 0 })
|
||||
@ -2642,7 +2642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let params: Vec<&hir::Param<'_>> = self
|
||||
let mut params: Vec<&hir::Param<'_>> = self
|
||||
.tcx
|
||||
.hir()
|
||||
.body(fn_node.body_id()?)
|
||||
@ -2651,7 +2651,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.skip(if is_method { 1 } else { 0 })
|
||||
.collect();
|
||||
|
||||
Some(generic_params.into_iter().zip_eq(params).collect())
|
||||
// The surrounding code expects variadic functions to not have a parameter representing
|
||||
// the "..." parameter. This is already true of the FnDecl but not of the body params, so
|
||||
// we drop it if it exists.
|
||||
|
||||
if fn_decl.c_variadic {
|
||||
params.pop();
|
||||
}
|
||||
|
||||
debug_assert_eq!(params.len(), generic_params.len());
|
||||
Some(generic_params.into_iter().zip(params).collect())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
//@ known-bug: rust-lang/rust#130372
|
||||
|
||||
pub fn variadic_fn(n: usize, mut args: ...) {}
|
||||
|
||||
reuse variadic_fn;
|
||||
|
||||
fn main() {
|
||||
variadic_fn();
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
//@ known-bug: rust-lang/rust#130372
|
||||
|
||||
pub fn test_va_copy(_: u64, mut ap: ...) {}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
test_va_copy();
|
||||
|
||||
call(x);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
//@ known-bug: rust-lang/rust#130372
|
||||
|
||||
fn bar() -> impl Fn() {
|
||||
wrap()
|
||||
}
|
||||
|
||||
fn wrap(...: impl ...) -> impl Fn() {}
|
@ -0,0 +1,12 @@
|
||||
#![feature(c_variadic)]
|
||||
|
||||
// Regression test that covers all 3 cases of https://github.com/rust-lang/rust/issues/130372
|
||||
|
||||
unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) {}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
test_va_copy();
|
||||
//~^ ERROR this function takes at least 1 argument but 0 arguments were supplied
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
error[E0060]: this function takes at least 1 argument but 0 arguments were supplied
|
||||
--> $DIR/mismatch-args-vargs-issue-130372.rs:9:9
|
||||
|
|
||||
LL | test_va_copy();
|
||||
| ^^^^^^^^^^^^-- argument #1 of type `u64` is missing
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/mismatch-args-vargs-issue-130372.rs:5:22
|
||||
|
|
||||
LL | unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) {}
|
||||
| ^^^^^^^^^^^^ ------
|
||||
help: provide the argument
|
||||
|
|
||||
LL | test_va_copy(/* u64 */);
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0060`.
|
Loading…
Reference in New Issue
Block a user