From 942d4c7e5486d28fbf852697995f8dcf804158fb Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Fri, 8 Apr 2016 08:13:29 +0300 Subject: [PATCH] Blacklist fn item types from being used with variadic functions. --- src/librustc_typeck/check/mod.rs | 21 +++++++++++++++------ src/test/compile-fail/issue-32201.rs | 22 ++++++++++++++++++++++ src/test/compile-fail/variadic-ffi-3.rs | 12 ++++++------ 3 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 src/test/compile-fail/issue-32201.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 45877d7099bbf..67b91f7838c66 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2578,24 +2578,33 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, ty::TyFloat(ast::FloatTy::F32) => { fcx.type_error_message(arg.span, |t| { - format!("can't pass an {} to variadic \ - function, cast to c_double", t) + format!("can't pass an `{}` to variadic \ + function, cast to `c_double`", t) }, arg_ty, None); } ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => { fcx.type_error_message(arg.span, |t| { - format!("can't pass {} to variadic \ - function, cast to c_int", + format!("can't pass `{}` to variadic \ + function, cast to `c_int`", t) }, arg_ty, None); } ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => { fcx.type_error_message(arg.span, |t| { - format!("can't pass {} to variadic \ - function, cast to c_uint", + format!("can't pass `{}` to variadic \ + function, cast to `c_uint`", t) }, arg_ty, None); } + ty::TyFnDef(_, _, f) => { + let ptr_ty = fcx.tcx().mk_ty(ty::TyFnPtr(f)); + let ptr_ty = fcx.infcx().resolve_type_vars_if_possible(&ptr_ty); + fcx.type_error_message(arg.span, + |t| { + format!("can't pass `{}` to variadic \ + function, cast to `{}`", t, ptr_ty) + }, arg_ty, None); + } _ => {} } } diff --git a/src/test/compile-fail/issue-32201.rs b/src/test/compile-fail/issue-32201.rs new file mode 100644 index 0000000000000..bcc53df68a323 --- /dev/null +++ b/src/test/compile-fail/issue-32201.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern { + fn foo(a: i32, ...); +} + +fn bar(_: *const u8) {} + +fn main() { + unsafe { + foo(0, bar); + //~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function, cast to `fn(*const u8)` + } +} diff --git a/src/test/compile-fail/variadic-ffi-3.rs b/src/test/compile-fail/variadic-ffi-3.rs index 1d5ebdbae3e2e..6e60562da6749 100644 --- a/src/test/compile-fail/variadic-ffi-3.rs +++ b/src/test/compile-fail/variadic-ffi-3.rs @@ -33,11 +33,11 @@ fn main() { //~| expected variadic fn //~| found non-variadic function - foo(1, 2, 3f32); //~ ERROR: can't pass an f32 to variadic function, cast to c_double - foo(1, 2, true); //~ ERROR: can't pass bool to variadic function, cast to c_int - foo(1, 2, 1i8); //~ ERROR: can't pass i8 to variadic function, cast to c_int - foo(1, 2, 1u8); //~ ERROR: can't pass u8 to variadic function, cast to c_uint - foo(1, 2, 1i16); //~ ERROR: can't pass i16 to variadic function, cast to c_int - foo(1, 2, 1u16); //~ ERROR: can't pass u16 to variadic function, cast to c_uint + foo(1, 2, 3f32); //~ ERROR: can't pass an `f32` to variadic function, cast to `c_double` + foo(1, 2, true); //~ ERROR: can't pass `bool` to variadic function, cast to `c_int` + foo(1, 2, 1i8); //~ ERROR: can't pass `i8` to variadic function, cast to `c_int` + foo(1, 2, 1u8); //~ ERROR: can't pass `u8` to variadic function, cast to `c_uint` + foo(1, 2, 1i16); //~ ERROR: can't pass `i16` to variadic function, cast to `c_int` + foo(1, 2, 1u16); //~ ERROR: can't pass `u16` to variadic function, cast to `c_uint` } }