Skip to content

Commit 627217f

Browse files
committed
valid cap clause for kind-ness too
1 parent c03d14a commit 627217f

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

src/comp/middle/kind.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,30 @@ fn check_fn_body(decl: fn_decl, body: blk, sp: span, i: fn_ident, id: node_id,
9090
visit::visit_fn_body(decl, body, sp, i, id, cx, v);
9191
}
9292

93-
fn check_fn_cap_clause(_cx: ctx,
94-
_id: node_id,
95-
_cap_clause: capture_clause) {
96-
// let freevars = freevars::get_freevars(cx.tcx, i);
97-
// let contains_var = lambda(id: def_id) -> bool {
98-
// vec::any(freevars, { |freevar|
99-
// ast_util::def_id_of_def(freevar).node == def_id
100-
// })
101-
// }
102-
// with_closure_check_fn(cx, id) { |check_fn|
103-
// let check_var = lambda(
104-
// }
93+
fn check_fn_cap_clause(cx: ctx,
94+
id: node_id,
95+
cap_clause: capture_clause) {
96+
// Check that the variables named in the clause which are not free vars
97+
// (if any) are also legal. freevars are checked above in check_fn_body.
98+
// This is kind of a degenerate case, as captured variables will generally
99+
// appear free in the body.
100+
let freevars = freevars::get_freevars(cx.tcx, id);
101+
let freevar_ids = vec::map(*freevars, { |freevar|
102+
ast_util::def_id_of_def(freevar.def).node
103+
});
104+
//log("freevar_ids", freevar_ids);
105+
with_closure_check_fn(cx, id) { |check_fn|
106+
let check_var = lambda(&&cap_item: @capture_item) {
107+
let cap_def = cx.tcx.def_map.get(cap_item.id);
108+
let cap_def_id = ast_util::def_id_of_def(cap_def).node;
109+
if !vec::member(cap_def_id, freevar_ids) {
110+
let ty = ty::node_id_to_type(cx.tcx, cap_def_id);
111+
check_fn(cx, ty, cap_item.span);
112+
}
113+
};
114+
vec::iter(cap_clause.copies, check_var);
115+
vec::iter(cap_clause.moves, check_var);
116+
}
105117
}
106118

107119
fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// error-pattern: copying a noncopyable value
2+
3+
fn to_lambda2(b: block(uint) -> uint) -> lambda(uint) -> uint {
4+
// test case where copy clause specifies a value that is not used
5+
// in lambda body, but value is illegal to copy:
6+
ret lambda[copy b](u: uint) -> uint { 22u };
7+
}
8+
9+
fn main() {
10+
}

0 commit comments

Comments
 (0)