@@ -18,7 +18,6 @@ import middle::ty::field;
18
18
import middle:: ty:: method;
19
19
import middle:: ty:: mo_val;
20
20
import middle:: ty:: mo_alias;
21
- import middle:: ty:: mo_either;
22
21
import middle:: ty:: node_type_table;
23
22
import middle:: ty:: pat_ty;
24
23
import middle:: ty:: path_to_str;
@@ -1401,52 +1400,60 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1401
1400
1402
1401
// A generic function to factor out common logic from call and bind
1403
1402
// expressions.
1404
- fn check_call_or_bind( & @fn_ctxt fcx, & @ast:: expr f,
1403
+ fn check_call_or_bind( & @fn_ctxt fcx, & span sp , & @ast:: expr f,
1405
1404
& vec[ option:: t[ @ast:: expr] ] args) {
1406
1405
// Check the function.
1407
1406
check_expr( fcx, f) ;
1408
1407
1409
- // Check the arguments and generate the argument signature.
1410
- let vec[ option:: t[ @ast:: expr] ] args_0 = [ ] ;
1411
- let vec[ arg] arg_tys_0 = [ ] ;
1408
+ // Get the function type. We need to have resolved it enough to know
1409
+ // it's a ty_fn or ty_native_fn.
1410
+ auto fty = expr_ty( fcx. ccx. tcx, f) ;
1411
+ fty = ty:: unify:: resolve_all_vars( fcx. ccx. tcx, fcx. var_bindings, fty) ;
1412
+
1413
+ // Grab the argument types and the return type.
1414
+ auto arg_tys;
1415
+ alt ( ty:: struct ( fcx. ccx. tcx, fty) ) {
1416
+ case ( ty:: ty_fn( _, ?arg_tys_0, _, _) ) {
1417
+ arg_tys = arg_tys_0;
1418
+ }
1419
+ case ( ty:: ty_native_fn( _, ?arg_tys_0, _) ) {
1420
+ arg_tys = arg_tys_0;
1421
+ }
1422
+ case ( _) {
1423
+ fcx. ccx. tcx. sess. span_err( f. span, "mismatched types: " +
1424
+ "expected function or native function but found " +
1425
+ ty_to_str( fcx. ccx. tcx, fty) ) ;
1426
+ }
1427
+ }
1428
+
1429
+ // Check that the correct number of arguments were supplied.
1430
+ auto expected_arg_count = vec:: len[ ty:: arg] ( arg_tys) ;
1431
+ auto supplied_arg_count = vec:: len[ option:: t[ @ast:: expr] ] ( args) ;
1432
+ if ( expected_arg_count != supplied_arg_count) {
1433
+ fcx. ccx. tcx. sess. span_err( sp,
1434
+ #fmt( "this function takes %u parameter%s but %u parameter%s \
1435
+ supplied",
1436
+ expected_arg_count,
1437
+ if ( expected_arg_count == 1 u) { "" } else { "s" } ,
1438
+ supplied_arg_count,
1439
+ if ( supplied_arg_count == 1 u) { " was" }
1440
+ else { "s were" } ) ) ;
1441
+ }
1442
+
1443
+ // Check the arguments.
1444
+ // TODO: iter2
1445
+ auto i = 0 u;
1412
1446
for ( option:: t[ @ast:: expr] a_opt in args) {
1413
1447
alt ( a_opt) {
1414
1448
case ( some( ?a) ) {
1415
1449
check_expr( fcx, a) ;
1416
- auto typ = expr_ty ( fcx. ccx . tcx , a) ;
1417
- vec :: push [ arg ] ( arg_tys_0 , rec ( mode=mo_either , ty=typ ) ) ;
1450
+ demand :: simple ( fcx, a. span , arg_tys . ( i ) . ty ,
1451
+ expr_ty ( fcx . ccx . tcx , a ) ) ;
1418
1452
}
1419
- case ( none) {
1420
- auto typ = next_ty_var( fcx) ;
1421
- vec:: push[ arg] ( arg_tys_0, rec( mode=mo_either, ty=typ) ) ;
1422
- }
1423
- }
1424
- }
1425
-
1426
- auto rt_0 = next_ty_var( fcx) ;
1427
- auto t_0;
1428
- alt ( struct ( fcx. ccx. tcx, expr_ty( fcx. ccx. tcx, f) ) ) {
1429
- case ( ty:: ty_fn( ?proto, _, _, ?cf) ) {
1430
- t_0 = ty:: mk_fn( fcx. ccx. tcx, proto, arg_tys_0, rt_0, cf) ;
1431
- }
1432
- case ( ty:: ty_native_fn( ?abi, _, _) ) {
1433
- t_0 = ty:: mk_native_fn( fcx. ccx. tcx, abi, arg_tys_0, rt_0) ;
1434
- }
1435
- case ( ?u) {
1436
- fcx. ccx. tcx. sess. span_err( f. span,
1437
- "check_call_or_bind(): fn expr doesn't have fn type,"
1438
- + " instead having: " +
1439
- ty_to_str( fcx. ccx. tcx,
1440
- expr_ty( fcx. ccx. tcx, f) ) ) ;
1453
+ case ( none) { /* no-op */ }
1441
1454
}
1455
+ i += 1 u;
1442
1456
}
1443
-
1444
- // Unify the callee and arguments.
1445
- auto f_ty = ty:: expr_ty( fcx. ccx. tcx, f) ;
1446
- auto f_tps = ty:: expr_ty_params_and_ty( fcx. ccx. tcx, f) . _0;
1447
- auto tpt_1 = demand:: full( fcx, f. span, f_ty, t_0, f_tps,
1448
- NO_AUTODEREF ) ;
1449
- //replace_expr_type(fcx, f, tpt_1);
1450
1457
}
1451
1458
1452
1459
// A generic function for checking assignment expressions
@@ -1461,14 +1468,15 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1461
1468
}
1462
1469
1463
1470
// A generic function for checking call expressions
1464
- fn check_call( & @fn_ctxt fcx, & @ast:: expr f, & vec[ @ast:: expr] args) {
1471
+ fn check_call( & @fn_ctxt fcx, & span sp, & @ast:: expr f,
1472
+ & vec[ @ast:: expr] args) {
1465
1473
let vec[ option:: t[ @ast:: expr] ] args_opt_0 = [ ] ;
1466
1474
for ( @ast:: expr arg in args) {
1467
1475
args_opt_0 += [ some[ @ast:: expr] ( arg) ] ;
1468
1476
}
1469
1477
1470
1478
// Call the generic checker.
1471
- check_call_or_bind( fcx, f, args_opt_0) ;
1479
+ check_call_or_bind( fcx, sp , f, args_opt_0) ;
1472
1480
}
1473
1481
1474
1482
// A generic function for checking for or for-each loops
@@ -1861,7 +1869,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1861
1869
1862
1870
case ( ast:: expr_bind( ?f, ?args, ?a) ) {
1863
1871
// Call the generic checker.
1864
- check_call_or_bind( fcx, f, args) ;
1872
+ check_call_or_bind( fcx, expr . span , f, args) ;
1865
1873
1866
1874
// Pull the argument and return types out.
1867
1875
auto proto_1;
@@ -1904,7 +1912,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1904
1912
function name onto purity-designation */
1905
1913
require_pure_call( fcx. ccx, fcx. purity, f, expr. span) ;
1906
1914
1907
- check_call( fcx, f, args) ;
1915
+ check_call( fcx, expr . span , f, args) ;
1908
1916
1909
1917
// Pull the return type out of the type of the function.
1910
1918
auto rt_1 = ty:: mk_nil( fcx. ccx. tcx) ; // FIXME: typestate botch
@@ -1959,7 +1967,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1959
1967
}
1960
1968
1961
1969
case ( ast:: expr_spawn( _, _, ?f, ?args, ?a) ) {
1962
- check_call( fcx, f, args) ;
1970
+ check_call( fcx, expr . span , f, args) ;
1963
1971
1964
1972
auto fty = expr_ty( fcx. ccx. tcx, f) ;
1965
1973
auto ret_ty = ty:: ret_ty_of_fn_ty( fcx. ccx. tcx, fty) ;
0 commit comments