@@ -8,11 +8,10 @@ import syntax::walk;
8
8
import metadata:: csearch;
9
9
import driver:: session;
10
10
import util:: common;
11
+ import util:: common:: * ;
11
12
import syntax:: codemap:: span;
12
13
import std:: map:: new_int_hash;
13
14
import std:: map:: new_str_hash;
14
- import util:: common:: new_def_hash;
15
- import util:: common:: log_expr_err;
16
15
import middle:: ty;
17
16
import middle:: ty:: node_id_to_type;
18
17
import middle:: ty:: arg;
@@ -1485,7 +1484,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1485
1484
// expressions.
1486
1485
1487
1486
fn check_call_or_bind( & @fn_ctxt fcx, & span sp, & @ast:: expr f,
1488
- & ( option:: t[ @ast:: expr] ) [ ] args, bool is_call ) {
1487
+ & ( option:: t[ @ast:: expr] ) [ ] args, call_kind call_kind ) {
1489
1488
// Check the function.
1490
1489
1491
1490
check_expr( fcx, f) ;
@@ -1494,8 +1493,9 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1494
1493
auto fty = expr_ty( fcx. ccx. tcx, f) ;
1495
1494
1496
1495
// We want to autoderef calls but not binds
1497
- auto fty_stripped =
1498
- if ( is_call) { do_autoderef( fcx, sp, fty) } else { fty } ;
1496
+ auto fty_stripped = alt ( call_kind) {
1497
+ case ( kind_call) { do_autoderef( fcx, sp, fty) }
1498
+ case ( _) { fty } } ;
1499
1499
1500
1500
// Grab the argument types and the return type.
1501
1501
auto arg_tys;
@@ -1532,13 +1532,38 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1532
1532
1533
1533
auto i = 0 u;
1534
1534
for ( option:: t[ @ast:: expr] a_opt in args) {
1535
+ auto check_ty_vars = call_kind == kind_spawn;
1535
1536
alt ( a_opt) {
1536
1537
case ( some( ?a) ) {
1537
1538
check_expr( fcx, a) ;
1538
1539
demand:: simple( fcx, a. span, arg_tys. ( i) . ty,
1539
1540
expr_ty( fcx. ccx. tcx, a) ) ;
1540
1541
}
1541
- case ( none) { /* no-op * / }
1542
+ case ( none) {
1543
+ check_ty_vars = true;
1544
+ }
1545
+ }
1546
+ /* If this argument is going to be a thunk argument
1547
+ (that is, it's an underscore-bind thing or a spawn
1548
+ argument), then it has to be either passed by reference,
1549
+ or have a statically known size. */
1550
+ alt ( call_kind) {
1551
+ case ( kind_call) { }
1552
+ case ( _) { /* bind or spawn */
1553
+ if ( check_ty_vars &&
1554
+ ( ( ty:: type_contains_params( fcx. ccx. tcx,
1555
+ arg_tys. ( i) . ty) )
1556
+ || ty:: type_contains_vars( fcx. ccx. tcx,
1557
+ arg_tys. ( i) . ty) )
1558
+ && arg_tys. ( i) . mode == mo_val) {
1559
+ // For why the check is necessary, see the
1560
+ // none case in trans_bind_thunk
1561
+ fcx. ccx. tcx. sess. span_fatal( sp,
1562
+ call_kind_str( call_kind) +
1563
+ " arguments with types containing parameters \
1564
+ must be passed by alias") ;
1565
+ }
1566
+ }
1542
1567
}
1543
1568
i += 1 u;
1544
1569
}
@@ -1556,14 +1581,14 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1556
1581
// A generic function for checking call expressions
1557
1582
1558
1583
fn check_call( & @fn_ctxt fcx, & span sp, & @ast:: expr f,
1559
- & ( @ast:: expr) [ ] args) {
1584
+ & ( @ast:: expr) [ ] args, call_kind call_kind ) {
1560
1585
let ( option:: t[ @ast:: expr] ) [ ] args_opt_0 = ~[ ] ;
1561
1586
for ( @ast:: expr arg in args) {
1562
1587
args_opt_0 += ~[ some[ @ast:: expr] ( arg) ] ;
1563
1588
}
1564
1589
// Call the generic checker.
1565
1590
1566
- check_call_or_bind( fcx, sp, f, args_opt_0, true ) ;
1591
+ check_call_or_bind( fcx, sp, f, args_opt_0, call_kind ) ;
1567
1592
}
1568
1593
// A generic function for checking for or for-each loops
1569
1594
@@ -1990,7 +2015,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1990
2015
case ( ast:: expr_bind( ?f, ?args) ) {
1991
2016
// Call the generic checker.
1992
2017
1993
- check_call_or_bind( fcx, expr. span, f, args, false ) ;
2018
+ check_call_or_bind( fcx, expr. span, f, args, kind_bind ) ;
1994
2019
// Pull the argument and return types out.
1995
2020
1996
2021
auto proto_1;
@@ -2035,7 +2060,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2035
2060
function name onto purity-designation */
2036
2061
2037
2062
require_pure_call( fcx. ccx, fcx. purity, f, expr. span) ;
2038
- check_call( fcx, expr. span, f, args) ;
2063
+ check_call( fcx, expr. span, f, args, kind_call ) ;
2039
2064
// Pull the return type out of the type of the function.
2040
2065
2041
2066
auto rt_1;
@@ -2085,7 +2110,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2085
2110
require_impure( fcx. ccx. tcx. sess, fcx. purity, expr. span) ;
2086
2111
}
2087
2112
case ( ast:: expr_spawn( _, _, ?f, ?args) ) {
2088
- check_call( fcx, expr. span, f, args) ;
2113
+ check_call( fcx, expr. span, f, args, kind_spawn ) ;
2089
2114
auto fty = expr_ty( fcx. ccx. tcx, f) ;
2090
2115
auto ret_ty = ty:: ret_ty_of_fn_ty( fcx. ccx. tcx, fty) ;
2091
2116
demand:: simple( fcx, f. span, ty:: mk_nil( fcx. ccx. tcx) , ret_ty) ;
0 commit comments