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:
parent
e50580aa66
commit
b8bb663df7
9 changed files with 25 additions and 37 deletions
|
@ -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 */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) { }
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// xfail-test
|
||||
// expected error: mismatched kinds
|
||||
// error-pattern: mismatched kinds
|
||||
|
||||
resource r(i: @mutable int) {
|
||||
*i = *i + 1;
|
||||
|
|
|
@ -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;
|
|
@ -1,5 +1,4 @@
|
|||
// xfail-test
|
||||
// expected error: mismatched kinds
|
||||
// error-pattern: mismatched kinds
|
||||
|
||||
resource r(i: @mutable int) {
|
||||
*i = *i + 1;
|
||||
|
|
|
@ -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>(); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue