From b8bb663df787511c6b91bf3182b59d140a9c8e02 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 27 Sep 2011 14:50:55 -0700 Subject: [PATCH] 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. --- src/comp/middle/kind.rs | 25 +++---------------- src/comp/middle/ty.rs | 9 ++++++- src/lib/ptr.rs | 6 ++--- src/lib/vec.rs | 6 ++--- src/test/compile-fail/copy-a-resource.rs | 5 +--- src/test/compile-fail/pinned-deep-copy.rs | 3 +-- .../unique-swap2.rs | 3 +++ src/test/compile-fail/unique-vec-res.rs | 3 +-- src/test/run-pass/unify-return-ty.rs | 2 +- 9 files changed, 25 insertions(+), 37 deletions(-) rename src/test/{run-pass => compile-fail}/unique-swap2.rs (74%) diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs index 3880d4c36015..c7f37e95c8cc 100644 --- a/src/comp/middle/kind.rs +++ b/src/comp/middle/kind.rs @@ -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 */ } } } } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 5dda7e74a99e..3e76ce2f93e5 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -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. diff --git a/src/lib/ptr.rs b/src/lib/ptr.rs index 8d730732c3cd..ccb05f0ce29d 100644 --- a/src/lib/ptr.rs +++ b/src/lib/ptr.rs @@ -5,9 +5,9 @@ native "rust-intrinsic" mod rusti { fn ptr_offset(ptr: *T, count: uint) -> *T; } -fn addr_of(val: T) -> *mutable T { ret rusti::addr_of(val); } -fn offset(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 { ret unsafe::reinterpret_cast(0u); } +fn null<@T>() -> *T { ret unsafe::reinterpret_cast(0u); } diff --git a/src/lib/vec.rs b/src/lib/vec.rs index 9b0e2a63091f..3bb03afb4834 100644 --- a/src/lib/vec.rs +++ b/src/lib/vec.rs @@ -345,18 +345,18 @@ mod unsafe { ret rustrt::vec_from_buf_shared(ptr, elts); } - fn set_len(&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::(); } - fn to_ptr(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(v: [T]) -> *T { ret unsafe::to_ptr(v); } +fn to_ptr<@T>(v: [T]) -> *T { ret unsafe::to_ptr(v); } // Local Variables: // mode: rust; diff --git a/src/test/compile-fail/copy-a-resource.rs b/src/test/compile-fail/copy-a-resource.rs index 0a1c65aecf98..030872a1348a 100644 --- a/src/test/compile-fail/copy-a-resource.rs +++ b/src/test/compile-fail/copy-a-resource.rs @@ -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) { } diff --git a/src/test/compile-fail/pinned-deep-copy.rs b/src/test/compile-fail/pinned-deep-copy.rs index 0ee39b071fe3..33570b4061fc 100644 --- a/src/test/compile-fail/pinned-deep-copy.rs +++ b/src/test/compile-fail/pinned-deep-copy.rs @@ -1,5 +1,4 @@ -// xfail-test -// expected error: mismatched kinds +// error-pattern: mismatched kinds resource r(i: @mutable int) { *i = *i + 1; diff --git a/src/test/run-pass/unique-swap2.rs b/src/test/compile-fail/unique-swap2.rs similarity index 74% rename from src/test/run-pass/unique-swap2.rs rename to src/test/compile-fail/unique-swap2.rs index 23f0c13f8956..c2d751483fb9 100644 --- a/src/test/run-pass/unique-swap2.rs +++ b/src/test/compile-fail/unique-swap2.rs @@ -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; diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index 7560de3bec06..94c5e538f981 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -1,5 +1,4 @@ -// xfail-test -// expected error: mismatched kinds +// error-pattern: mismatched kinds resource r(i: @mutable int) { *i = *i + 1; diff --git a/src/test/run-pass/unify-return-ty.rs b/src/test/run-pass/unify-return-ty.rs index 5bfdeb33847b..b8f9a39f50bd 100644 --- a/src/test/run-pass/unify-return-ty.rs +++ b/src/test/run-pass/unify-return-ty.rs @@ -4,6 +4,6 @@ use std; import std::unsafe; -fn null() -> *T { unsafe::reinterpret_cast(0) } +fn null<@T>() -> *T { unsafe::reinterpret_cast(0) } fn main() { null::(); }