@@ -1872,6 +1872,22 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) {
1872
1872
check_call_or_bind( scx, f, args_opt_0) ;
1873
1873
}
1874
1874
1875
+ // A generic function for checking for or for-each loops
1876
+ fn check_for_or_for_each( & @stmt_ctxt scx, & @ast:: decl decl,
1877
+ & ty:: t element_ty, & ast:: block body,
1878
+ uint node_id) {
1879
+ check_decl_local( scx. fcx, decl) ;
1880
+ check_block( scx, body) ;
1881
+
1882
+ // Unify type of decl with element type of the seq
1883
+ demand:: simple( scx, decl. span, ty:: decl_local_ty( scx. fcx. ccx. tcx,
1884
+ decl) ,
1885
+ element_ty) ;
1886
+
1887
+ auto typ = ty:: mk_nil( scx. fcx. ccx. tcx) ;
1888
+ write:: ty_only_fixup( scx, node_id, typ) ;
1889
+ }
1890
+
1875
1891
alt ( expr. node) {
1876
1892
case ( ast:: expr_lit( ?lit, ?a) ) {
1877
1893
auto typ = check_lit( scx. fcx. ccx, lit) ;
@@ -2000,8 +2016,7 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) {
2000
2016
case ( none[ @ast:: expr] ) {
2001
2017
auto nil = ty:: mk_nil( scx. fcx. ccx. tcx) ;
2002
2018
if ( !are_compatible( scx, scx. fcx. ret_ty, nil) ) {
2003
- // TODO: span_err
2004
- scx. fcx. ccx. tcx. sess. span_err( expr. span,
2019
+ scx. fcx. ccx. tcx. sess. span_err( expr. span,
2005
2020
"put; in iterator yielding non-nil" ) ;
2006
2021
}
2007
2022
@@ -2159,24 +2174,33 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) {
2159
2174
}
2160
2175
2161
2176
case ( ast:: expr_for( ?decl, ?seq, ?body, ?a) ) {
2162
- check_decl_local( scx. fcx, decl) ;
2163
2177
check_expr( scx, seq) ;
2164
- check_block( scx, body) ;
2165
-
2166
- // FIXME: enforce that the type of the decl is the element type
2167
- // of the seq.
2168
-
2169
- auto typ = ty:: mk_nil( scx. fcx. ccx. tcx) ;
2170
- write:: ty_only_fixup( scx, a. id, typ) ;
2178
+ alt ( struct ( scx. fcx. ccx. tcx,
2179
+ expr_ty( scx. fcx. ccx. tcx, seq) ) ) {
2180
+ // FIXME: I include the check_for_or_each call in
2181
+ // each case because of a bug in typestate;
2182
+ // once that bug is fixed, the call can be moved
2183
+ // out of the alt expression
2184
+ case ( ty:: ty_vec( ?vec_elt_ty) ) {
2185
+ auto elt_ty = vec_elt_ty. ty;
2186
+ check_for_or_for_each( scx, decl, elt_ty, body, a. id) ;
2187
+ }
2188
+ case ( ty:: ty_str) {
2189
+ auto elt_ty = ty:: mk_mach( scx. fcx. ccx. tcx,
2190
+ util:: common:: ty_u8) ;
2191
+ check_for_or_for_each( scx, decl, elt_ty, body, a. id) ;
2192
+ }
2193
+ case ( _) {
2194
+ scx. fcx. ccx. tcx. sess. span_err( expr. span,
2195
+ "type of for loop iterator is not a vector or string" ) ;
2196
+ }
2197
+ }
2171
2198
}
2172
2199
2173
2200
case ( ast:: expr_for_each( ?decl, ?seq, ?body, ?a) ) {
2174
- check_decl_local( scx. fcx, decl) ;
2175
2201
check_expr( scx, seq) ;
2176
- check_block( scx, body) ;
2177
-
2178
- auto typ = ty:: mk_nil( scx. fcx. ccx. tcx) ;
2179
- write:: ty_only_fixup( scx, a. id, typ) ;
2202
+ check_for_or_for_each( scx, decl, expr_ty( scx. fcx. ccx. tcx, seq) ,
2203
+ body, a. id) ;
2180
2204
}
2181
2205
2182
2206
case ( ast:: expr_while( ?cond, ?body, ?a) ) {
0 commit comments