Skip to content

Commit

Permalink
Reject programs that do a put outside of iterators.
Browse files Browse the repository at this point in the history
  • Loading branch information
msullivan committed Aug 3, 2011
1 parent 8871462 commit c9ae548
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 6 deletions.
11 changes: 7 additions & 4 deletions src/comp/middle/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type fn_ctxt =
// (and with any functions whose environment is being captured).
{ret_ty: ty::t,
purity: ast::purity,
proto: ast::proto,
var_bindings: @ty::unify::var_bindings,
locals: hashmap[ast::node_id, int],
local_names: hashmap[ast::node_id, ast::ident],
Expand Down Expand Up @@ -1883,22 +1884,24 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
}
ast::expr_put(expr_opt) {
require_impure(tcx.sess, fcx.purity, expr.span);
if (fcx.proto != ast::proto_iter) {
tcx.sess.span_fatal(expr.span, "put in non-iterator");
}
alt expr_opt {
none. {
let nil = ty::mk_nil(tcx);
if !are_compatible(fcx, fcx.ret_ty, nil) {
tcx.sess.span_fatal(expr.span,
"put; in iterator yielding non-nil");
}
write::nil_ty(tcx, id);
}
some(e) {
bot = check_expr(fcx, e);
demand::simple(fcx, expr.span, fcx.ret_ty,
expr_ty(tcx, e));
write::nil_ty(tcx, id);
}
}
write::nil_ty(tcx, id);
}
ast::expr_be(e) {
// FIXME: prove instead of assert
Expand Down Expand Up @@ -2619,12 +2622,12 @@ fn check_const(ccx: &@crate_ctxt, sp: &span, e: &@ast::expr,
id: &ast::node_id) {
// FIXME: this is kinda a kludge; we manufacture a fake function context
// and statement context for checking the initializer expression.

let rty = node_id_to_type(ccx.tcx, id);
let fixups: ast::node_id[] = ~[];
let fcx: @fn_ctxt =
@{ret_ty: rty,
purity: ast::pure_fn,
proto: ast::proto_fn,
var_bindings: ty::unify::mk_var_bindings(),
locals: new_int_hash[int](),
local_names: new_int_hash[ast::ident](),
Expand All @@ -2643,13 +2646,13 @@ fn check_fn(ccx: &@crate_ctxt, f: &ast::_fn, id: &ast::node_id,
let fcx: @fn_ctxt =
@{ret_ty: ast_ty_to_ty_crate(ccx, decl.output),
purity: decl.purity,
proto: f.proto,
var_bindings: gather_result.var_bindings,
locals: gather_result.locals,
local_names: gather_result.local_names,
next_var_id: gather_result.next_var_id,
mutable fixups: fixups,
ccx: ccx};

check_block(fcx, body);
alt decl.purity {
ast::pure_fn. {
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/put-in-fn.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// xfail-stage1
// xfail-stage2
// xfail-stage3
// error-pattern: iterator function
// error-pattern:put in non-iterator

fn f() -> int { put 10; }

fn main() { }
fn main() { }

0 comments on commit c9ae548

Please sign in to comment.