make sure we do not bind unique closures (or blocks, for that matter)
This commit is contained in:
parent
8478349b8b
commit
12c68bcd6d
3 changed files with 43 additions and 10 deletions
|
@ -2394,6 +2394,16 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
_ { fail "LHS of bind expr didn't have a function type?!"; }
|
||||
}
|
||||
|
||||
let proto = alt proto {
|
||||
ast::proto_bare | ast::proto_box { ast::proto_box }
|
||||
ast::proto_uniq | ast::proto_any | ast::proto_block {
|
||||
tcx.sess.span_err(expr.span,
|
||||
#fmt["cannot bind %s closures",
|
||||
proto_to_str(proto)]);
|
||||
proto // dummy value so compilation can proceed
|
||||
}
|
||||
};
|
||||
|
||||
// For each blank argument, add the type of that argument
|
||||
// to the resulting function type.
|
||||
let out_args = [];
|
||||
|
@ -2406,16 +2416,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
i += 1u;
|
||||
}
|
||||
|
||||
// Determine what fn prototype results from binding
|
||||
fn lower_bound_proto(proto: ast::proto) -> ast::proto {
|
||||
// FIXME: This is right for bare fns, possibly not others
|
||||
alt proto {
|
||||
ast::proto_bare { ast::proto_box }
|
||||
_ { proto }
|
||||
}
|
||||
}
|
||||
|
||||
let ft = ty::mk_fn(tcx, {proto: lower_bound_proto(proto),
|
||||
let ft = ty::mk_fn(tcx, {proto: proto,
|
||||
inputs: out_args, output: rt,
|
||||
ret_style: cf, constraints: constrs});
|
||||
write_ty(tcx, id, ft);
|
||||
|
|
10
src/test/compile-fail/bind-stack-closure.rs
Normal file
10
src/test/compile-fail/bind-stack-closure.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
fn foo(x: fn()) {
|
||||
bind x(); //! ERROR cannot bind fn closures
|
||||
}
|
||||
|
||||
fn bar(x: fn&()) {
|
||||
bind x(); //! ERROR cannot bind fn& closures
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
22
src/test/compile-fail/bind-unique-closure.rs
Normal file
22
src/test/compile-fail/bind-unique-closure.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
// -*- rust -*-
|
||||
|
||||
// I originally made this test to ensure that bind does the right
|
||||
// thing when binding a unique closure (which is to copy the closure,
|
||||
// I suppose?). But I've since decided it's not worth the effort, and
|
||||
// so I just made it a simple error. But I left the test as is in
|
||||
// case we ever decide that bind should work with unique closures,
|
||||
// though a simpler test would suffice for now.
|
||||
|
||||
fn make_addr(-x: ~int) -> fn~() -> uint {
|
||||
(fn~[move x]() -> uint { ptr::addr_of(*x) as uint })
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = ~3;
|
||||
let a = ptr::addr_of(*x) as uint;
|
||||
let adder: fn~() -> uint = make_addr(x);
|
||||
let bound_adder: fn~() -> uint = bind adder();
|
||||
//!^ ERROR cannot bind fn~ closures
|
||||
assert adder() == a;
|
||||
assert bound_adder() != a;
|
||||
}
|
Loading…
Reference in a new issue