rustc_typeck: don't use double indirection to Expr's in check_argument_types.

This commit is contained in:
Eduard Burtescu 2015-01-08 18:26:36 +02:00
parent 2c76710ece
commit 21ec0c85d9
2 changed files with 21 additions and 23 deletions

View File

@ -192,11 +192,10 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
fcx.normalize_associated_types_in(call_expr.span, &fn_sig); fcx.normalize_associated_types_in(call_expr.span, &fn_sig);
// Call the generic checker. // Call the generic checker.
let arg_exprs: Vec<_> = arg_exprs.iter().collect(); // for some weird reason we take &[&P<...>].
check_argument_types(fcx, check_argument_types(fcx,
call_expr.span, call_expr.span,
fn_sig.inputs.as_slice(), fn_sig.inputs.as_slice(),
arg_exprs.as_slice(), arg_exprs,
AutorefArgs::No, AutorefArgs::No,
fn_sig.variadic, fn_sig.variadic,
TupleArgumentsFlag::DontTupleArguments); TupleArgumentsFlag::DontTupleArguments);
@ -209,12 +208,11 @@ fn confirm_overloaded_call<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
arg_exprs: &[P<ast::Expr>], arg_exprs: &[P<ast::Expr>],
method_callee: ty::MethodCallee<'tcx>) method_callee: ty::MethodCallee<'tcx>)
{ {
let arg_exprs: Vec<_> = arg_exprs.iter().collect(); // for some weird reason we take &[&P<...>].
let output_type = check_method_argument_types(fcx, let output_type = check_method_argument_types(fcx,
call_expr.span, call_expr.span,
method_callee.ty, method_callee.ty,
call_expr, call_expr,
arg_exprs.as_slice(), arg_exprs,
AutorefArgs::No, AutorefArgs::No,
TupleArgumentsFlag::TupleArguments); TupleArgumentsFlag::TupleArguments);
let method_call = ty::MethodCall::expr(call_expr.id); let method_call = ty::MethodCall::expr(call_expr.id);

View File

@ -112,6 +112,7 @@ use std::cell::{Cell, Ref, RefCell};
use std::mem::replace; use std::mem::replace;
use std::rc::Rc; use std::rc::Rc;
use std::iter::repeat; use std::iter::repeat;
use std::slice;
use syntax::{self, abi, attr}; use syntax::{self, abi, attr};
use syntax::ast::{self, ProvidedMethod, RequiredMethod, TypeTraitItem, DefId}; use syntax::ast::{self, ProvidedMethod, RequiredMethod, TypeTraitItem, DefId};
use syntax::ast_util::{self, local_def, PostExpansionMethod}; use syntax::ast_util::{self, local_def, PostExpansionMethod};
@ -2598,7 +2599,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
sp: Span, sp: Span,
method_fn_ty: Ty<'tcx>, method_fn_ty: Ty<'tcx>,
callee_expr: &ast::Expr, callee_expr: &ast::Expr,
args_no_rcvr: &[&P<ast::Expr>], args_no_rcvr: &[P<ast::Expr>],
autoref_args: AutorefArgs, autoref_args: AutorefArgs,
tuple_arguments: TupleArgumentsFlag) tuple_arguments: TupleArgumentsFlag)
-> ty::FnOutput<'tcx> { -> ty::FnOutput<'tcx> {
@ -2624,7 +2625,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// HACK(eddyb) ignore self in the definition (see above). // HACK(eddyb) ignore self in the definition (see above).
check_argument_types(fcx, check_argument_types(fcx,
sp, sp,
fty.sig.0.inputs.slice_from(1), &fty.sig.0.inputs[1..],
args_no_rcvr, args_no_rcvr,
autoref_args, autoref_args,
fty.sig.0.variadic, fty.sig.0.variadic,
@ -2644,7 +2645,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
sp: Span, sp: Span,
fn_inputs: &[Ty<'tcx>], fn_inputs: &[Ty<'tcx>],
args: &[&P<ast::Expr>], args: &[P<ast::Expr>],
autoref_args: AutorefArgs, autoref_args: AutorefArgs,
variadic: bool, variadic: bool,
tuple_arguments: TupleArgumentsFlag) { tuple_arguments: TupleArgumentsFlag) {
@ -2767,7 +2768,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
AutorefArgs::No => {} AutorefArgs::No => {}
} }
check_expr_coercable_to_type(fcx, &***arg, formal_ty); check_expr_coercable_to_type(fcx, &**arg, formal_ty);
} }
} }
} }
@ -2776,12 +2777,12 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// arguments which we skipped above. // arguments which we skipped above.
if variadic { if variadic {
for arg in args.iter().skip(expected_arg_count) { for arg in args.iter().skip(expected_arg_count) {
check_expr(fcx, &***arg); check_expr(fcx, &**arg);
// There are a few types which get autopromoted when passed via varargs // There are a few types which get autopromoted when passed via varargs
// in C but we just error out instead and require explicit casts. // in C but we just error out instead and require explicit casts.
let arg_ty = structurally_resolved_type(fcx, arg.span, let arg_ty = structurally_resolved_type(fcx, arg.span,
fcx.expr_ty(&***arg)); fcx.expr_ty(&**arg));
match arg_ty.sty { match arg_ty.sty {
ty::ty_float(ast::TyF32) => { ty::ty_float(ast::TyF32) => {
fcx.type_error_message(arg.span, fcx.type_error_message(arg.span,
@ -3064,12 +3065,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
}; };
// Call the generic checker. // Call the generic checker.
let args: Vec<_> = args[1..].iter().map(|x| x).collect();
let ret_ty = check_method_argument_types(fcx, let ret_ty = check_method_argument_types(fcx,
method_name.span, method_name.span,
fn_ty, fn_ty,
expr, expr,
args.as_slice(), &args[1..],
AutorefArgs::No, AutorefArgs::No,
DontTupleArguments); DontTupleArguments);
@ -3167,8 +3167,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
None => None None => None
}; };
let args = match rhs { let args = match rhs {
Some(rhs) => vec![rhs], Some(rhs) => slice::ref_slice(rhs),
None => vec![] None => &[][]
}; };
match method { match method {
Some(method) => { Some(method) => {
@ -3177,12 +3177,12 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
let method_call = ::middle::ty::MethodCall::expr(op_ex.id); let method_call = ::middle::ty::MethodCall::expr(op_ex.id);
fcx.inh.method_map.borrow_mut().insert(method_call, method); fcx.inh.method_map.borrow_mut().insert(method_call, method);
match check_method_argument_types(fcx, match check_method_argument_types(fcx,
op_ex.span, op_ex.span,
method_ty, method_ty,
op_ex, op_ex,
args.as_slice(), args,
autoref_args, autoref_args,
DontTupleArguments) { DontTupleArguments) {
ty::FnConverging(result_type) => result_type, ty::FnConverging(result_type) => result_type,
ty::FnDiverging => fcx.tcx().types.err ty::FnDiverging => fcx.tcx().types.err
} }
@ -3196,7 +3196,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
op_ex.span, op_ex.span,
expected_ty, expected_ty,
op_ex, op_ex,
args.as_slice(), args,
autoref_args, autoref_args,
DontTupleArguments); DontTupleArguments);
fcx.tcx().types.err fcx.tcx().types.err
@ -4045,10 +4045,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
fcx.write_ty(id, fcx.node_ty(b.id)); fcx.write_ty(id, fcx.node_ty(b.id));
} }
ast::ExprCall(ref callee, ref args) => { ast::ExprCall(ref callee, ref args) => {
callee::check_call(fcx, expr, &**callee, args.as_slice()); callee::check_call(fcx, expr, &**callee, &args[]);
} }
ast::ExprMethodCall(ident, ref tps, ref args) => { ast::ExprMethodCall(ident, ref tps, ref args) => {
check_method_call(fcx, expr, ident, args.as_slice(), tps.as_slice(), lvalue_pref); check_method_call(fcx, expr, ident, &args[], &tps[], lvalue_pref);
let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a)); let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
let args_err = arg_tys.fold(false, let args_err = arg_tys.fold(false,
|rest_err, a| { |rest_err, a| {