Skip to content

Commit bbb8bde

Browse files
committed
Slight cleanup
1 parent 555119f commit bbb8bde

File tree

3 files changed

+43
-35
lines changed

3 files changed

+43
-35
lines changed

compiler/rustc_typeck/src/check/callee.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
496496
call_expr.span,
497497
call_expr,
498498
fn_sig.inputs(),
499-
&expected_arg_tys,
499+
expected_arg_tys,
500500
arg_exprs,
501501
fn_sig.c_variadic,
502502
TupleArgumentsFlag::DontTupleArguments,
@@ -529,7 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
529529
call_expr.span,
530530
call_expr,
531531
fn_sig.inputs(),
532-
&expected_arg_tys,
532+
expected_arg_tys,
533533
arg_exprs,
534534
fn_sig.c_variadic,
535535
TupleArgumentsFlag::TupleArguments,

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+27-33
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6262
sp,
6363
expr,
6464
&err_inputs,
65-
&[],
65+
vec![],
6666
args_no_rcvr,
6767
false,
6868
tuple_arguments,
@@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8383
sp,
8484
expr,
8585
&method.sig.inputs()[1..],
86-
&expected_input_tys[..],
86+
expected_input_tys,
8787
args_no_rcvr,
8888
method.sig.c_variadic,
8989
tuple_arguments,
@@ -103,7 +103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
103103
// Types (as defined in the *signature* of the target function)
104104
formal_input_tys: &[Ty<'tcx>],
105105
// More specific expected types, after unifying with caller output types
106-
expected_input_tys: &[Ty<'tcx>],
106+
expected_input_tys: Vec<Ty<'tcx>>,
107107
// The expressions for each provided argument
108108
provided_args: &'tcx [hir::Expr<'tcx>],
109109
// Whether the function is variadic, for example when imported from C
@@ -249,25 +249,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
249249
err.emit();
250250
};
251251

252-
let mut expected_input_tys = expected_input_tys.to_vec();
253-
254-
let formal_input_tys = if tuple_arguments == TupleArguments {
252+
let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
255253
let tuple_type = self.structurally_resolved_type(call_span, formal_input_tys[0]);
256254
match tuple_type.kind() {
257255
ty::Tuple(arg_types) if arg_types.len() != provided_args.len() => {
258256
param_count_error(arg_types.len(), provided_args.len(), "E0057", false, false);
259-
expected_input_tys = vec![];
260-
self.err_args(provided_args.len())
257+
(self.err_args(provided_args.len()), vec![])
261258
}
262259
ty::Tuple(arg_types) => {
263-
expected_input_tys = match expected_input_tys.get(0) {
260+
let expected_input_tys = match expected_input_tys.get(0) {
264261
Some(&ty) => match ty.kind() {
265262
ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
266263
_ => vec![],
267264
},
268265
None => vec![],
269266
};
270-
arg_types.iter().map(|k| k.expect_ty()).collect()
267+
(arg_types.iter().map(|k| k.expect_ty()).collect(), expected_input_tys)
271268
}
272269
_ => {
273270
struct_span_err!(
@@ -278,19 +275,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
278275
for the function trait is neither a tuple nor unit"
279276
)
280277
.emit();
281-
expected_input_tys = vec![];
282-
self.err_args(provided_args.len())
278+
(self.err_args(provided_args.len()), vec![])
283279
}
284280
}
285281
} else if expected_arg_count == supplied_arg_count {
286-
formal_input_tys.to_vec()
282+
(formal_input_tys.to_vec(), expected_input_tys)
287283
} else if c_variadic {
288284
if supplied_arg_count >= expected_arg_count {
289-
formal_input_tys.to_vec()
285+
(formal_input_tys.to_vec(), expected_input_tys)
290286
} else {
291287
param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
292-
expected_input_tys = vec![];
293-
self.err_args(supplied_arg_count)
288+
(self.err_args(supplied_arg_count), vec![])
294289
}
295290
} else {
296291
// is the missing argument of type `()`?
@@ -303,8 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
303298
};
304299
param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
305300

306-
expected_input_tys = vec![];
307-
self.err_args(supplied_arg_count)
301+
(self.err_args(supplied_arg_count), vec![])
308302
};
309303

310304
debug!(
@@ -319,6 +313,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
319313
formal_input_tys.clone()
320314
};
321315

316+
assert_eq!(expected_input_tys.len(), formal_input_tys.len());
317+
318+
// Keep track of the fully coerced argument types
322319
let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
323320

324321
// We introduce a helper function to demand that a given argument satisfy a given input
@@ -376,8 +373,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
376373
// that we have more information about the types of arguments when we
377374
// type-check the functions. This isn't really the right way to do this.
378375
for check_closures in [false, true] {
379-
debug!("check_closures={}", check_closures);
380-
381376
// More awful hacks: before we check argument types, try to do
382377
// an "opportunistic" trait resolution of any trait bounds on
383378
// the call. This helps coercions.
@@ -394,31 +389,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
394389
})
395390
}
396391

397-
// For C-variadic functions, we don't have a declared type for all of
398-
// the arguments hence we only do our usual type checking with
399-
// the arguments who's types we do know.
400-
let t = if c_variadic {
401-
expected_arg_count
402-
} else if tuple_arguments == TupleArguments {
403-
provided_args.len()
404-
} else {
405-
supplied_arg_count
406-
};
407-
for (i, arg) in provided_args.iter().take(t).enumerate() {
392+
let minimum_input_count = formal_input_tys.len();
393+
for (idx, arg) in provided_args.iter().enumerate() {
408394
// Warn only for the first loop (the "no closures" one).
409395
// Closure arguments themselves can't be diverging, but
410396
// a previous argument can, e.g., `foo(panic!(), || {})`.
411397
if !check_closures {
412398
self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
413399
}
414400

415-
let is_closure = matches!(arg.kind, ExprKind::Closure(..));
401+
// For C-variadic functions, we don't have a declared type for all of
402+
// the arguments hence we only do our usual type checking with
403+
// the arguments who's types we do know. However, we *can* check
404+
// for unreachable expressions (see above).
405+
// FIXME: unreachable warning current isn't emitted
406+
if idx >= minimum_input_count {
407+
continue;
408+
}
416409

410+
let is_closure = matches!(arg.kind, ExprKind::Closure(..));
417411
if is_closure != check_closures {
418412
continue;
419413
}
420414

421-
demand_compatible(i, &mut final_arg_types);
415+
demand_compatible(idx, &mut final_arg_types);
422416
}
423417
}
424418

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-pass
2+
3+
#![feature(c_variadic)]
4+
5+
extern "C" {
6+
fn foo(f: isize, x: u8, ...);
7+
}
8+
9+
fn main() {
10+
unsafe {
11+
// FIXME: Ideally we could give an unreachable warning
12+
foo(1, loop {}, 1usize);
13+
}
14+
}

0 commit comments

Comments
 (0)