Skip to content

Commit 4bee452

Browse files
committed
Don't allow copying of unique boxes of pinned kinds
Issue #409
1 parent 2d5e085 commit 4bee452

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

src/comp/middle/kind.rs

+32-19
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
*
8585
*/
8686

87-
import syntax::{ast, ast_util, visit};
87+
import syntax::{ast, ast_util, visit, codemap};
8888
import std::{vec, option, str};
8989
import ast::{kind, kind_unique, kind_shared, kind_pinned};
9090

@@ -122,12 +122,18 @@ fn need_expr_kind(tcx: ty::ctxt, e: @ast::expr, k_need: ast::kind,
122122
kind_to_str(k_need), kind_to_str(tk.kind),
123123
util::ppaux::ty_to_str(tcx, tk.ty)];
124124

125-
if !kind_lteq(k_need, tk.kind) {
125+
demand_kind(tcx, e.span, tk.ty, k_need, descr);
126+
}
127+
128+
fn demand_kind(tcx: ty::ctxt, sp: codemap::span, t: ty::t,
129+
k_need: ast::kind, descr: str) {
130+
let k = ty::type_kind(tcx, t);
131+
if !kind_lteq(k_need, k) {
126132
let s =
127133
#fmt["mismatched kinds for %s: needed %s type, got %s type %s",
128-
descr, kind_to_str(k_need), kind_to_str(tk.kind),
129-
util::ppaux::ty_to_str(tcx, tk.ty)];
130-
tcx.sess.span_err(e.span, s);
134+
descr, kind_to_str(k_need), kind_to_str(k),
135+
util::ppaux::ty_to_str(tcx, t)];
136+
tcx.sess.span_err(sp, s);
131137
}
132138
}
133139

@@ -136,16 +142,30 @@ fn need_shared_lhs_rhs(tcx: ty::ctxt, a: @ast::expr, b: @ast::expr, op: str) {
136142
need_expr_kind(tcx, b, ast::kind_shared, op + " rhs");
137143
}
138144

145+
// Additional checks for copyability that require a little more nuance
146+
fn check_copy(tcx: ty::ctxt, e: @ast::expr) {
147+
alt ty::struct(tcx, ty::expr_ty(tcx, e)) {
148+
// Unique boxes most not contain pinned kinds
149+
ty::ty_uniq(mt) {
150+
demand_kind(tcx, e.span, mt.ty, ast::kind_shared,
151+
"unique box interior");
152+
}
153+
_ { }
154+
}
155+
}
156+
139157
fn check_expr(tcx: ty::ctxt, e: @ast::expr) {
140158
alt e.node {
141159

142-
// FIXME: These rules do not implement the copy type-constructor
143-
// discrimination described by the block comment at the top of
144-
// this file. This code is wrong; it lets you copy anything
145-
// shared-kind.
160+
// FIXME: These rules do not fully implement the copy type-constructor
161+
// discrimination described by the block comment at the top of this
162+
// file. This code is wrong; it lets you copy anything shared-kind.
146163

147164
ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); }
148-
ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, "="); }
165+
ast::expr_assign(a, b) {
166+
need_shared_lhs_rhs(tcx, a, b, "=");
167+
check_copy(tcx, b);
168+
}
149169
ast::expr_assign_op(_, a, b) { need_shared_lhs_rhs(tcx, a, b, "op="); }
150170
ast::expr_swap(a, b) { need_shared_lhs_rhs(tcx, a, b, "<->"); }
151171
ast::expr_copy(a) {
@@ -174,15 +194,8 @@ fn check_expr(tcx: ty::ctxt, e: @ast::expr) {
174194
assert (vec::len(item_tk.kinds) == vec::len(tpt.params));
175195
for k_need: ast::kind in item_tk.kinds {
176196
let t = tpt.params[i];
177-
let k = ty::type_kind(tcx, t);
178-
if !kind_lteq(k_need, k) {
179-
let s =
180-
#fmt["mismatched kinds for typaram %d: \
181-
needed %s type, got %s type %s",
182-
i, kind_to_str(k_need), kind_to_str(k),
183-
util::ppaux::ty_to_str(tcx, t)];
184-
tcx.sess.span_err(e.span, s);
185-
}
197+
demand_kind(tcx, e.span, t, k_need,
198+
#fmt("typaram %d", i));
186199
i += 1;
187200
}
188201
}

src/test/compile-fail/unique-pinned-nocopy.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// xfail-test
21
// error-pattern: mismatched kind
32

43
resource r(b: bool) {

0 commit comments

Comments
 (0)