@@ -1122,9 +1122,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1122
1122
unifier : & fn ( ) ) {
1123
1123
debug ! ( ">> typechecking %s" , fcx. expr_to_str( expr) ) ;
1124
1124
1125
- // A generic function to factor out common logic from call and
1126
- // overloaded operations
1127
- fn check_call_inner (
1125
+ fn check_argument_types (
1128
1126
fcx : @mut FnCtxt ,
1129
1127
sp : span ,
1130
1128
call_expr_id : ast:: node_id ,
@@ -1134,18 +1132,24 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1134
1132
sugar : ast:: CallSugar ,
1135
1133
deref_args : DerefArgs ) -> ty:: t
1136
1134
{
1135
+ /*!
1136
+ *
1137
+ * Generic function that factors out common logic from
1138
+ * function calls, method calls and overloaded operators.
1139
+ */
1140
+
1137
1141
let tcx = fcx. ccx . tcx ;
1138
1142
1139
1143
// Replace all region parameters in the arguments and return
1140
1144
// type with fresh region variables.
1141
1145
1142
- debug ! ( "check_call_inner : before universal quant., in_fty=%s" ,
1146
+ debug ! ( "check_argument_types : before universal quant., in_fty=%s" ,
1143
1147
fcx. infcx( ) . ty_to_str( in_fty) ) ;
1144
1148
1145
- let formal_tys ;
1149
+ let sty = structure_of ( fcx , sp , in_fty ) ;
1146
1150
1147
1151
// FIXME(#3678) For now, do not permit calls to C abi functions.
1148
- match structure_of ( fcx , sp , in_fty ) {
1152
+ match sty {
1149
1153
ty:: ty_bare_fn( ty:: BareFnTy { abis, _} ) => {
1150
1154
if !abis. is_rust ( ) {
1151
1155
tcx. sess . span_err (
@@ -1157,68 +1161,65 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1157
1161
_ => { }
1158
1162
}
1159
1163
1160
- // This is subtle: we expect `fty` to be a function type, which
1161
- // normally introduce a level of binding. In this case, we want to
1162
- // process the types bound by the function but not by any nested
1163
- // functions. Therefore, we match one level of structure.
1164
- let ret_ty = match structure_of ( fcx, sp, in_fty) {
1165
- ty:: ty_bare_fn( ty:: BareFnTy { sig : ref sig, _} ) |
1166
- ty:: ty_closure( ty:: ClosureTy { sig : ref sig, _} ) => {
1167
- let ( _, _, sig) =
1168
- replace_bound_regions_in_fn_sig (
1169
- tcx, @Nil , None , sig,
1170
- |_br| fcx. infcx ( ) . next_region_var (
1171
- sp, call_expr_id) ) ;
1172
-
1173
- let supplied_arg_count = args. len ( ) ;
1174
-
1175
- // Grab the argument types, supplying fresh type variables
1176
- // if the wrong number of arguments were supplied
1177
- let expected_arg_count = sig. inputs . len ( ) ;
1178
- formal_tys = if expected_arg_count == supplied_arg_count {
1179
- sig. inputs . map ( |a| a. ty )
1180
- } else {
1181
- let suffix = match sugar {
1182
- ast:: NoSugar => "" ,
1183
- ast:: DoSugar => " (including the closure passed by \
1184
- the `do` keyword)",
1185
- ast:: ForSugar => " (including the closure passed by \
1186
- the `for` keyword)"
1187
- } ;
1188
- let msg = fmt ! ( "this function takes %u parameter%s but \
1189
- %u parameter%s supplied%s",
1190
- expected_arg_count,
1191
- if expected_arg_count == 1 { "" }
1192
- else { "s" } ,
1193
- supplied_arg_count,
1194
- if supplied_arg_count == 1 { " was" }
1195
- else { "s were" } ,
1196
- suffix) ;
1197
-
1198
- tcx. sess . span_err ( sp, msg) ;
1199
-
1200
- vec:: from_fn ( supplied_arg_count, |_| ty:: mk_err ( tcx) )
1201
- } ;
1202
-
1203
- sig. output
1204
- }
1205
-
1164
+ // Extract the function signature from `in_fty`.
1165
+ let sig = match sty {
1166
+ ty:: ty_bare_fn( ty:: BareFnTy { sig : sig, _} ) |
1167
+ ty:: ty_closure( ty:: ClosureTy { sig : sig, _} ) => sig,
1206
1168
_ => {
1207
1169
fcx. type_error_message ( sp, |actual| {
1208
- fmt ! ( "expected function or foreign function but \
1170
+ fmt ! ( "expected function but \
1209
1171
found `%s`", actual) } , in_fty, None ) ;
1210
1172
1211
1173
// check each arg against "error", in order to set up
1212
1174
// all the node type bindings
1213
- formal_tys = args. map ( |_x| ty:: mk_err ( tcx) ) ;
1214
- ty:: mk_err ( tcx)
1175
+ FnSig { bound_lifetime_names : opt_vec:: Empty ,
1176
+ inputs : args. map ( |_x| ty:: arg { mode : ast:: expl ( ast:: by_copy) ,
1177
+ ty : ty:: mk_err ( tcx) } ) ,
1178
+ output : ty:: mk_err ( tcx) }
1215
1179
}
1216
1180
} ;
1217
1181
1218
- debug ! ( "check_call_inner: after universal quant., \
1219
- formal_tys=%? ret_ty=%s",
1182
+ // Replace any bound regions that appear in the function
1183
+ // signature with region variables
1184
+ let ( _, _, sig) =
1185
+ replace_bound_regions_in_fn_sig (
1186
+ tcx, @Nil , None , & sig,
1187
+ |_br| fcx. infcx ( ) . next_region_var (
1188
+ sp, call_expr_id) ) ;
1189
+
1190
+ // Grab the argument types, supplying fresh type variables
1191
+ // if the wrong number of arguments were supplied
1192
+ let supplied_arg_count = args. len ( ) ;
1193
+ let expected_arg_count = sig. inputs . len ( ) ;
1194
+ let formal_tys = if expected_arg_count == supplied_arg_count {
1195
+ sig. inputs . map ( |a| a. ty )
1196
+ } else {
1197
+ let suffix = match sugar {
1198
+ ast:: NoSugar => "" ,
1199
+ ast:: DoSugar => " (including the closure passed by \
1200
+ the `do` keyword)",
1201
+ ast:: ForSugar => " (including the closure passed by \
1202
+ the `for` keyword)"
1203
+ } ;
1204
+ let msg = fmt ! ( "this function takes %u parameter%s but \
1205
+ %u parameter%s supplied%s",
1206
+ expected_arg_count,
1207
+ if expected_arg_count == 1 { "" }
1208
+ else { "s" } ,
1209
+ supplied_arg_count,
1210
+ if supplied_arg_count == 1 { " was" }
1211
+ else { "s were" } ,
1212
+ suffix) ;
1213
+
1214
+ tcx. sess . span_err ( sp, msg) ;
1215
+
1216
+ vec:: from_elem ( supplied_arg_count, ty:: mk_err ( tcx) )
1217
+ } ;
1218
+
1219
+ debug ! ( "check_argument_types: after universal quant., \
1220
+ formal_tys=%? sig.output=%s",
1220
1221
formal_tys. map( |t| fcx. infcx( ) . ty_to_str( * t) ) ,
1221
- fcx. infcx( ) . ty_to_str( ret_ty ) ) ;
1222
+ fcx. infcx( ) . ty_to_str( sig . output ) ) ;
1222
1223
1223
1224
// Check the arguments.
1224
1225
// We do this in a pretty awful way: first we typecheck any arguments
@@ -1269,7 +1270,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1269
1270
}
1270
1271
}
1271
1272
1272
- ret_ty
1273
+ sig . output
1273
1274
}
1274
1275
1275
1276
// A generic function for checking assignment expressions
@@ -1284,43 +1285,23 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1284
1285
// The callee checks for bot / err, we don't need to
1285
1286
}
1286
1287
1287
- // A generic function for doing all of the checking for call or
1288
- // method expressions
1289
- fn check_call_or_method ( fcx : @mut FnCtxt ,
1290
- sp : span ,
1291
- call_expr_id : ast:: node_id ,
1292
- fn_ty : ty:: t ,
1293
- expr : @ast:: expr ,
1294
- args : & [ @ast:: expr ] ,
1295
- sugar : ast:: CallSugar )
1296
- {
1297
-
1298
- // Call the generic checker.
1299
- let ret_ty = check_call_inner ( fcx, sp, call_expr_id,
1300
- fn_ty, expr, args, sugar,
1301
- DontDerefArgs ) ;
1302
- // Pull the return type out of the type of the function.
1303
- fcx. write_ty ( call_expr_id, ret_ty) ;
1304
- // Callee checks for bot and err, no need for that
1305
- }
1306
-
1307
1288
// A generic function for doing all of the checking for call expressions
1308
1289
fn check_call ( fcx : @mut FnCtxt ,
1309
- sp : span ,
1310
- call_expr_id : ast:: node_id ,
1290
+ call_expr : @ast:: expr ,
1311
1291
f : @ast:: expr ,
1312
1292
args : & [ @ast:: expr ] ,
1313
1293
sugar : ast:: CallSugar ) {
1314
1294
// Index expressions need to be handled separately, to inform them
1315
1295
// that they appear in call position.
1316
- let mut _bot = check_expr ( fcx, f) ;
1317
- check_call_or_method ( fcx,
1318
- sp,
1319
- call_expr_id,
1320
- fcx. expr_ty ( f) ,
1321
- f,
1322
- args,
1323
- sugar)
1296
+ check_expr ( fcx, f) ;
1297
+
1298
+ // Call the generic checker.
1299
+ let ret_ty = check_argument_types ( fcx, call_expr. span , call_expr. id ,
1300
+ fcx. expr_ty ( f) , f, args, sugar,
1301
+ DontDerefArgs ) ;
1302
+
1303
+ // Pull the return type out of the type of the function.
1304
+ fcx. write_ty ( call_expr. id , ret_ty) ;
1324
1305
}
1325
1306
1326
1307
// Checks a method call.
@@ -1369,13 +1350,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1369
1350
}
1370
1351
}
1371
1352
1372
- check_call_or_method ( fcx,
1373
- expr. span ,
1374
- expr. id ,
1375
- fcx. node_ty ( expr. callee_id ) ,
1376
- expr,
1377
- args,
1378
- sugar)
1353
+ // Call the generic checker.
1354
+ let fn_ty = fcx. node_ty ( expr. callee_id ) ;
1355
+ let ret_ty = check_argument_types ( fcx, expr. span , expr. id ,
1356
+ fn_ty, expr, args, sugar,
1357
+ DontDerefArgs ) ;
1358
+
1359
+ // Pull the return type out of the type of the function.
1360
+ fcx. write_ty ( expr. id , ret_ty) ;
1379
1361
}
1380
1362
1381
1363
// A generic function for checking the then and else in an if
@@ -1423,20 +1405,20 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1423
1405
let method_ty = fcx. node_ty ( op_ex. callee_id ) ;
1424
1406
let method_map = fcx. inh . method_map ;
1425
1407
method_map. insert ( op_ex. id , * origin) ;
1426
- check_call_inner ( fcx, op_ex. span ,
1427
- op_ex. id , method_ty,
1428
- op_ex, args,
1429
- ast:: NoSugar , deref_args)
1408
+ check_argument_types ( fcx, op_ex. span ,
1409
+ op_ex. id , method_ty,
1410
+ op_ex, args,
1411
+ ast:: NoSugar , deref_args)
1430
1412
}
1431
1413
_ => {
1432
1414
let tcx = fcx. tcx ( ) ;
1433
1415
unbound_method ( ) ;
1434
1416
// Check the args anyway
1435
1417
// so we get all the error messages
1436
1418
let expected_ty = ty:: mk_err ( tcx) ;
1437
- check_call_inner ( fcx, op_ex. span , op_ex. id ,
1438
- expected_ty, op_ex, args,
1439
- ast:: NoSugar , deref_args) ;
1419
+ check_argument_types ( fcx, op_ex. span , op_ex. id ,
1420
+ expected_ty, op_ex, args,
1421
+ ast:: NoSugar , deref_args) ;
1440
1422
ty:: mk_err ( tcx)
1441
1423
}
1442
1424
}
@@ -2546,7 +2528,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
2546
2528
fcx.write_ty(id, fcx.node_ty(b.node.id));
2547
2529
}
2548
2530
ast::expr_call(f, ref args, sugar) => {
2549
- check_call(fcx, expr.span, expr.id , f, *args, sugar);
2531
+ check_call(fcx, expr, f, *args, sugar);
2550
2532
let f_ty = fcx.expr_ty(f);
2551
2533
let (args_bot, args_err) = args.foldl((false, false),
2552
2534
|&(rest_bot, rest_err), a| {
0 commit comments