@@ -1122,15 +1122,43 @@ 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
- fn check_argument_types (
1125
+ fn check_method_argument_types (
1126
1126
fcx : @mut FnCtxt ,
1127
1127
sp : span ,
1128
- call_expr_id : ast:: node_id ,
1129
- in_fty : ty:: t ,
1128
+ method_fn_ty : ty:: t ,
1130
1129
callee_expr : @ast:: expr ,
1131
1130
args : & [ @ast:: expr ] ,
1132
1131
sugar : ast:: CallSugar ,
1133
1132
deref_args : DerefArgs ) -> ty:: t
1133
+ {
1134
+ match ty:: get ( method_fn_ty) . sty {
1135
+ ty:: ty_bare_fn( ref fty) => {
1136
+ check_argument_types ( fcx, sp, fty. sig . inputs , callee_expr,
1137
+ args, sugar, deref_args) ;
1138
+ fty. sig . output
1139
+ }
1140
+ ty:: ty_err => {
1141
+ let err_inputs = err_args ( fcx. tcx ( ) , args. len ( ) ) ;
1142
+ check_argument_types ( fcx, sp, err_inputs, callee_expr,
1143
+ args, sugar, deref_args) ;
1144
+ method_fn_ty
1145
+ }
1146
+ _ => {
1147
+ fcx. tcx ( ) . sess . span_bug (
1148
+ sp,
1149
+ fmt ! ( "Method without bare fn type" ) ) ;
1150
+ }
1151
+ }
1152
+ }
1153
+
1154
+ fn check_argument_types (
1155
+ fcx : @mut FnCtxt ,
1156
+ sp : span ,
1157
+ fn_inputs : & [ ty:: arg ] ,
1158
+ callee_expr : @ast:: expr ,
1159
+ args : & [ @ast:: expr ] ,
1160
+ sugar : ast:: CallSugar ,
1161
+ deref_args : DerefArgs )
1134
1162
{
1135
1163
/*!
1136
1164
*
@@ -1140,59 +1168,12 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1140
1168
1141
1169
let tcx = fcx. ccx . tcx ;
1142
1170
1143
- // Replace all region parameters in the arguments and return
1144
- // type with fresh region variables.
1145
-
1146
- debug ! ( "check_argument_types: before universal quant., in_fty=%s" ,
1147
- fcx. infcx( ) . ty_to_str( in_fty) ) ;
1148
-
1149
- let sty = structure_of ( fcx, sp, in_fty) ;
1150
-
1151
- // FIXME(#3678) For now, do not permit calls to C abi functions.
1152
- match sty {
1153
- ty:: ty_bare_fn( ty:: BareFnTy { abis, _} ) => {
1154
- if !abis. is_rust ( ) {
1155
- tcx. sess . span_err (
1156
- sp,
1157
- fmt ! ( "Calls to C ABI functions are not (yet) \
1158
- supported; be patient, dear user") ) ;
1159
- }
1160
- }
1161
- _ => { }
1162
- }
1163
-
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,
1168
- _ => {
1169
- fcx. type_error_message ( sp, |actual| {
1170
- fmt ! ( "expected function but \
1171
- found `%s`", actual) } , in_fty, None ) ;
1172
-
1173
- // check each arg against "error", in order to set up
1174
- // all the node type bindings
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) }
1179
- }
1180
- } ;
1181
-
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
1171
// Grab the argument types, supplying fresh type variables
1191
1172
// if the wrong number of arguments were supplied
1192
1173
let supplied_arg_count = args. len ( ) ;
1193
- let expected_arg_count = sig . inputs . len ( ) ;
1174
+ let expected_arg_count = fn_inputs . len ( ) ;
1194
1175
let formal_tys = if expected_arg_count == supplied_arg_count {
1195
- sig . inputs . map ( |a| a. ty )
1176
+ fn_inputs . map ( |a| a. ty )
1196
1177
} else {
1197
1178
let suffix = match sugar {
1198
1179
ast:: NoSugar => "" ,
@@ -1216,10 +1197,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1216
1197
vec:: from_elem ( supplied_arg_count, ty:: mk_err ( tcx) )
1217
1198
} ;
1218
1199
1219
- debug ! ( "check_argument_types: after universal quant., \
1220
- formal_tys=%? sig.output=%s",
1221
- formal_tys. map( |t| fcx. infcx( ) . ty_to_str( * t) ) ,
1222
- fcx. infcx( ) . ty_to_str( sig. output) ) ;
1200
+ debug ! ( "check_argument_types: formal_tys=%?" ,
1201
+ formal_tys. map( |t| fcx. infcx( ) . ty_to_str( * t) ) ) ;
1223
1202
1224
1203
// Check the arguments.
1225
1204
// We do this in a pretty awful way: first we typecheck any arguments
@@ -1269,8 +1248,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1269
1248
}
1270
1249
}
1271
1250
}
1251
+ }
1272
1252
1273
- sig. output
1253
+ fn err_args ( tcx : ty:: ctxt , len : uint ) -> ~[ ty:: arg ] {
1254
+ vec:: from_fn ( len, |_| ty:: arg { mode : ast:: expl ( ast:: by_copy) ,
1255
+ ty : ty:: mk_err ( tcx) } )
1274
1256
}
1275
1257
1276
1258
// A generic function for checking assignment expressions
@@ -1295,13 +1277,53 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1295
1277
// that they appear in call position.
1296
1278
check_expr ( fcx, f) ;
1297
1279
1280
+
1281
+ // Extract the function signature from `in_fty`.
1282
+ let fn_ty = fcx. expr_ty ( f) ;
1283
+ let fn_sty = structure_of ( fcx, f. span , fn_ty) ;
1284
+
1285
+ // FIXME(#3678) For now, do not permit calls to C abi functions.
1286
+ match fn_sty {
1287
+ ty:: ty_bare_fn( ty:: BareFnTy { abis, _} ) => {
1288
+ if !abis. is_rust ( ) {
1289
+ fcx. tcx ( ) . sess . span_err (
1290
+ call_expr. span ,
1291
+ fmt ! ( "Calls to C ABI functions are not (yet) \
1292
+ supported; be patient, dear user") ) ;
1293
+ }
1294
+ }
1295
+ _ => { }
1296
+ }
1297
+
1298
+ let fn_sig = match fn_sty {
1299
+ ty:: ty_bare_fn( ty:: BareFnTy { sig : sig, _} ) |
1300
+ ty:: ty_closure( ty:: ClosureTy { sig : sig, _} ) => sig,
1301
+ _ => {
1302
+ fcx. type_error_message ( call_expr. span , |actual| {
1303
+ fmt ! ( "expected function but \
1304
+ found `%s`", actual) } , fn_ty, None ) ;
1305
+
1306
+ // check each arg against "error", in order to set up
1307
+ // all the node type bindings
1308
+ FnSig { bound_lifetime_names : opt_vec:: Empty ,
1309
+ inputs : err_args ( fcx. tcx ( ) , args. len ( ) ) ,
1310
+ output : ty:: mk_err ( fcx. tcx ( ) ) }
1311
+ }
1312
+ } ;
1313
+
1314
+ // Replace any bound regions that appear in the function
1315
+ // signature with region variables
1316
+ let ( _, _, fn_sig) =
1317
+ replace_bound_regions_in_fn_sig (
1318
+ fcx. tcx ( ) , @Nil , None , & fn_sig,
1319
+ |_br| fcx. infcx ( ) . next_region_var ( call_expr. span , call_expr. id ) ) ;
1320
+
1298
1321
// 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 ) ;
1322
+ check_argument_types ( fcx, call_expr. span , fn_sig. inputs , f,
1323
+ args, sugar, DontDerefArgs ) ;
1302
1324
1303
1325
// Pull the return type out of the type of the function.
1304
- fcx. write_ty ( call_expr. id , ret_ty ) ;
1326
+ fcx. write_ty ( call_expr. id , fn_sig . output ) ;
1305
1327
}
1306
1328
1307
1329
// Checks a method call.
@@ -1313,6 +1335,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1313
1335
tps : & [ @ast:: Ty ] ,
1314
1336
sugar : ast:: CallSugar ) {
1315
1337
check_expr ( fcx, rcvr) ;
1338
+
1316
1339
// no need to check for bot/err -- callee does that
1317
1340
let expr_t = structurally_resolved_type ( fcx,
1318
1341
expr. span ,
@@ -1352,9 +1375,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1352
1375
1353
1376
// Call the generic checker.
1354
1377
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 ) ;
1378
+ let ret_ty = check_method_argument_types ( fcx, expr. span ,
1379
+ fn_ty, expr, args, sugar,
1380
+ DontDerefArgs ) ;
1358
1381
1359
1382
// Pull the return type out of the type of the function.
1360
1383
fcx. write_ty ( expr. id , ret_ty) ;
@@ -1405,20 +1428,19 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
1405
1428
let method_ty = fcx. node_ty ( op_ex. callee_id ) ;
1406
1429
let method_map = fcx. inh . method_map ;
1407
1430
method_map. insert ( op_ex. id , * origin) ;
1408
- check_argument_types ( fcx, op_ex. span ,
1409
- op_ex. id , method_ty,
1410
- op_ex, args,
1411
- ast:: NoSugar , deref_args)
1431
+ check_method_argument_types ( fcx, op_ex. span ,
1432
+ method_ty, op_ex, args,
1433
+ ast:: NoSugar , deref_args)
1412
1434
}
1413
1435
_ => {
1414
1436
let tcx = fcx. tcx ( ) ;
1415
1437
unbound_method ( ) ;
1416
1438
// Check the args anyway
1417
1439
// so we get all the error messages
1418
1440
let expected_ty = ty:: mk_err ( tcx) ;
1419
- check_argument_types ( fcx, op_ex. span , op_ex . id ,
1420
- expected_ty, op_ex, args,
1421
- ast:: NoSugar , deref_args) ;
1441
+ check_method_argument_types ( fcx, op_ex. span ,
1442
+ expected_ty, op_ex, args,
1443
+ ast:: NoSugar , deref_args) ;
1422
1444
ty:: mk_err ( tcx)
1423
1445
}
1424
1446
}
0 commit comments