// We also need to make sure we at least write the ty of the other
// arguments which we skipped above.
if variadic {
+ fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
+ type_error_struct!(s, span, t, E0617,
+ "can't pass `{}` to variadic function, cast to `{}`",
+ t, cast_ty).emit();
+ }
+
for arg in args.iter().skip(expected_arg_count) {
let arg_ty = self.check_expr(&arg);
// There are a few types which get autopromoted when passed via varargs
// in C but we just error out instead and require explicit casts.
- let arg_ty = self.structurally_resolved_type(arg.span,
- arg_ty);
+ let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
match arg_ty.sty {
ty::TyFloat(ast::FloatTy::F32) => {
- self.type_error_message(arg.span, |t| {
- format!("can't pass an `{}` to variadic \
- function, cast to `c_double`", t)
- }, arg_ty);
+ variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
}
ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
- self.type_error_message(arg.span, |t| {
- format!("can't pass `{}` to variadic \
- function, cast to `c_int`",
- t)
- }, arg_ty);
+ variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
}
ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
- self.type_error_message(arg.span, |t| {
- format!("can't pass `{}` to variadic \
- function, cast to `c_uint`",
- t)
- }, arg_ty);
+ variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
}
ty::TyFnDef(.., f) => {
let ptr_ty = self.tcx.mk_fn_ptr(f);
let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
- self.type_error_message(arg.span,
- |t| {
- format!("can't pass `{}` to variadic \
- function, cast to `{}`", t, ptr_ty)
- }, arg_ty);
+ variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty));
}
_ => {}
}