Skip to content

Commit 8e2af5a

Browse files
committed
---
yaml --- r: 2833 b: refs/heads/master c: b6e0c58 h: refs/heads/master i: 2831: 547f67a v: v3
1 parent 296820f commit 8e2af5a

File tree

3 files changed

+63
-16
lines changed

3 files changed

+63
-16
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 0c5a55f2755138a6ddd2fbdfc7b11a4117409c5e
2+
refs/heads/master: b6e0c5829f5bb87b9a3f0f74b1d98f6ea4cc8cef

trunk/src/comp/middle/typeck.rs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,22 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) {
18721872
check_call_or_bind(scx, f, args_opt_0);
18731873
}
18741874

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+
18751891
alt (expr.node) {
18761892
case (ast::expr_lit(?lit, ?a)) {
18771893
auto typ = check_lit(scx.fcx.ccx, lit);
@@ -2000,8 +2016,7 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) {
20002016
case (none[@ast::expr]) {
20012017
auto nil = ty::mk_nil(scx.fcx.ccx.tcx);
20022018
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,
20052020
"put; in iterator yielding non-nil");
20062021
}
20072022

@@ -2159,24 +2174,33 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) {
21592174
}
21602175

21612176
case (ast::expr_for(?decl, ?seq, ?body, ?a)) {
2162-
check_decl_local(scx.fcx, decl);
21632177
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+
}
21712198
}
21722199

21732200
case (ast::expr_for_each(?decl, ?seq, ?body, ?a)) {
2174-
check_decl_local(scx.fcx, decl);
21752201
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);
21802204
}
21812205

21822206
case (ast::expr_while(?cond, ?body, ?a)) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// error-pattern: mismatched types
2+
use std;
3+
import std::map::hashmap;
4+
import std::bitv;
5+
6+
type fn_info = rec(hashmap[uint, var_info] vars);
7+
type var_info = rec(uint a, uint b);
8+
9+
fn bitv_to_str(fn_info enclosing, bitv::t v) -> str {
10+
auto s = "";
11+
12+
// error is that the value type in the hash map is var_info, not a tuple
13+
for each (@tup(uint, tup(uint, uint)) p in enclosing.vars.items()) {
14+
if (bitv::get(v, p._1._0)) {
15+
s += "foo"; // " " + p._1._1 + " " + "[" + p._0 + "]";
16+
}
17+
}
18+
ret s;
19+
}
20+
21+
fn main() {
22+
log "OK";
23+
}

0 commit comments

Comments
 (0)