Make it again possible to initialize resource locals via assignment

Some special cases allow both 'let a <- my_resource(x)' and
'let a = my_resource(x)' to work as expected despite ostensibly being
copies and moves.
This commit is contained in:
Brian Anderson 2011-09-27 22:40:15 -07:00
parent 459353e107
commit a96b16e8c3
5 changed files with 28 additions and 26 deletions

View File

@ -183,6 +183,12 @@ fn need_shared_or_pinned_ctor(tcx: ty::ctxt, a: @ast::expr, descr: str) {
ast::expr_rec(_, _) {
true
}
ast::expr_unary(ast::uniq(_), _) {
true
}
ast::expr_tup(_) {
true
}
_ { false }
}
}
@ -266,14 +272,12 @@ fn check_stmt(tcx: ty::ctxt, stmt: @ast::stmt) {
for (let_style, local) in locals {
alt local.node.init {
option::some({op: ast::init_assign., expr}) {
need_expr_kind(tcx, expr,
ast::kind_shared,
"local initializer");
need_shared_or_pinned_ctor(tcx, expr,
"local initializer");
}
option::some({op: ast::init_move., expr}) {
// FIXME: Should be as above but moving may be the
// only way available currently to assign a resource
// to a local.
need_shared_or_pinned_ctor(tcx, expr,
"local initializer");
}
option::none. { /* fall through */ }
}

View File

@ -1,12 +0,0 @@
// error-pattern: mismatched kind
resource r(b: bool) {
}
fn main() {
// Kind analysis considers this a copy, which isn't strictly true,
// but for many assignment initializers could be. To actually
// assign a resource to a local we can still use a move
// initializer.
let i = r(true);
}

View File

@ -1,8 +0,0 @@
// error-pattern: mismatched kind
resource r(b: bool) {
}
fn main() {
let i = ~r(true);
}

View File

@ -0,0 +1,7 @@
resource r(i: int) {
}
fn main() {
// Even though this looks like a copy, it's guaranteed not to be
let a = r(0);
}

View File

@ -0,0 +1,11 @@
resource r(i: @mutable int) {
*i = *i + 1;
}
fn main() {
let i = @mutable 0;
{
let j = ~r(i);
}
assert *i == 1;
}