1
Fork 0

Don't ever raise unique kinds of pinned kinds to shared (again)

So *resource, ~resource, [resource] are all pinned. This is counter to the
design of the kind system, but this way is a much clearer path to type safety.
Once we've established a good baseline with lots of tests, then we can try to
make raising pinned kinds work.
This commit is contained in:
Brian Anderson 2011-09-27 14:50:55 -07:00
parent e50580aa66
commit b8bb663df7
9 changed files with 25 additions and 37 deletions

View file

@ -142,22 +142,6 @@ fn need_shared_lhs_rhs(tcx: ty::ctxt, a: @ast::expr, b: @ast::expr, op: str) {
need_expr_kind(tcx, b, ast::kind_shared, op + " rhs");
}
// Additional checks for copyability that require a little more nuance
fn check_copy(tcx: ty::ctxt, e: @ast::expr) {
alt ty::struct(tcx, ty::expr_ty(tcx, e)) {
// Unique boxes most not contain pinned kinds
ty::ty_uniq(mt) {
demand_kind(tcx, e.span, mt.ty, ast::kind_shared,
"unique box interior");
}
ty::ty_vec(mt) {
demand_kind(tcx, e.span, mt.ty, ast::kind_shared,
"vector interior");
}
_ { }
}
}
fn check_expr(tcx: ty::ctxt, e: @ast::expr) {
alt e.node {
@ -168,16 +152,13 @@ fn check_expr(tcx: ty::ctxt, e: @ast::expr) {
ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); }
ast::expr_assign(a, b) {
need_shared_lhs_rhs(tcx, a, b, "=");
check_copy(tcx, b);
}
ast::expr_assign_op(_, a, b) {
need_shared_lhs_rhs(tcx, a, b, "op=");
check_copy(tcx, b);
}
ast::expr_swap(a, b) { need_shared_lhs_rhs(tcx, a, b, "<->"); }
ast::expr_copy(a) {
need_expr_kind(tcx, a, ast::kind_shared, "'copy' operand");
check_copy(tcx, a);
}
ast::expr_ret(option::some(a)) {
need_expr_kind(tcx, a, ast::kind_shared, "'ret' operand");
@ -221,9 +202,11 @@ fn check_stmt(tcx: ty::ctxt, stmt: @ast::stmt) {
need_expr_kind(tcx, expr,
ast::kind_shared,
"local initializer");
check_copy(tcx, expr);
}
_ { /* fall through */ }
option::some({op: ast::init_move., expr}) {
// FIXME: Same as above
}
option::none. { /* fall through */ }
}
}
}

View file

@ -1022,7 +1022,14 @@ fn type_kind(cx: ctxt, ty: t) -> ast::kind {
// Pointers and unique containers raise pinned to shared.
ty_ptr(tm) | ty_vec(tm) | ty_uniq(tm) {
let k = type_kind(cx, tm.ty);
if k == ast::kind_pinned { k = ast::kind_shared; }
// FIXME (984) Doing this implies a lot of subtle rules about what can
// and can't be copied, so I'm going to start by not raising unique of
// pinned to shared, make sure that's relatively safe, then we can try
// to make this work.
// if k == ast::kind_pinned { k = ast::kind_shared; }
result = kind::lower_kind(result, k);
}
// Records lower to the lowest of their members.

View file

@ -5,9 +5,9 @@ native "rust-intrinsic" mod rusti {
fn ptr_offset<T>(ptr: *T, count: uint) -> *T;
}
fn addr_of<T>(val: T) -> *mutable T { ret rusti::addr_of(val); }
fn offset<T>(ptr: *T, count: uint) -> *T {
fn addr_of<@T>(val: T) -> *mutable T { ret rusti::addr_of(val); }
fn offset<@T>(ptr: *T, count: uint) -> *T {
ret rusti::ptr_offset(ptr, count);
}
fn null<T>() -> *T { ret unsafe::reinterpret_cast(0u); }
fn null<@T>() -> *T { ret unsafe::reinterpret_cast(0u); }

View file

@ -345,18 +345,18 @@ mod unsafe {
ret rustrt::vec_from_buf_shared(ptr, elts);
}
fn set_len<T>(&v: [T], new_len: uint) {
fn set_len<@T>(&v: [T], new_len: uint) {
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
(**repr).fill = new_len * sys::size_of::<T>();
}
fn to_ptr<T>(v: [T]) -> *T {
fn to_ptr<@T>(v: [T]) -> *T {
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
}
}
fn to_ptr<T>(v: [T]) -> *T { ret unsafe::to_ptr(v); }
fn to_ptr<@T>(v: [T]) -> *T { ret unsafe::to_ptr(v); }
// Local Variables:
// mode: rust;

View file

@ -1,7 +1,4 @@
// error-pattern:Copying a non-copyable type
// This is still not properly checked
// xfail-test
// error-pattern:mismatched kinds
resource foo(i: int) { }

View file

@ -1,5 +1,4 @@
// xfail-test
// expected error: mismatched kinds
// error-pattern: mismatched kinds
resource r(i: @mutable int) {
*i = *i + 1;

View file

@ -1,3 +1,4 @@
// error-pattern:mismatched kinds
resource r(i: @mutable int) {
*i += 1;
@ -9,6 +10,8 @@ fn test1() {
{
let x <- ~r(i);
let y <- ~r(j);
// This is currently not allowed because ~resource is pinned.
// Note that ~resource is supposed to be shared.
x <-> y;
assert ***x == 200;
assert ***y == 100;

View file

@ -1,5 +1,4 @@
// xfail-test
// expected error: mismatched kinds
// error-pattern: mismatched kinds
resource r(i: @mutable int) {
*i = *i + 1;

View file

@ -4,6 +4,6 @@
use std;
import std::unsafe;
fn null<T>() -> *T { unsafe::reinterpret_cast(0) }
fn null<@T>() -> *T { unsafe::reinterpret_cast(0) }
fn main() { null::<int>(); }