Skip to content

Commit 1b8b0b8

Browse files
committed
Properly check for copies when constructing a record using with
Closes #989
1 parent 1ce3a84 commit 1b8b0b8

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/comp/middle/kind.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,23 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
5959
expr_copy(expr) { check_copy_ex(cx, expr, false); }
6060
// Vector add copies.
6161
expr_binary(add., ls, rs) { maybe_copy(cx, ls); maybe_copy(cx, rs); }
62-
expr_rec(fields, _) {
62+
expr_rec(fields, def) {
6363
for field in fields { maybe_copy(cx, field.node.expr); }
64+
alt def {
65+
some(ex) {
66+
// All noncopyable fields must be overridden
67+
let t = ty::expr_ty(cx.tcx, ex);
68+
let ty_fields = alt ty::struct(cx.tcx, t) { ty::ty_rec(f) { f } };
69+
for tf in ty_fields {
70+
if !std::vec::any({|f| f.node.ident == tf.ident}, fields) &&
71+
ty::type_kind(cx.tcx, tf.mt.ty) == kind_noncopyable {
72+
cx.tcx.sess.span_err(ex.span,
73+
"copying a noncopyable value");
74+
}
75+
}
76+
}
77+
_ {}
78+
}
6479
}
6580
expr_tup(exprs) | expr_vec(exprs, _) {
6681
for expr in exprs { maybe_copy(cx, expr); }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// error-pattern: copying a noncopyable value
2+
3+
resource my_resource(x: int) {
4+
log_err x;
5+
}
6+
7+
fn main() {
8+
{
9+
let a = {x: 0, y: my_resource(20)};
10+
let b = {x: 2 with a};
11+
log_err (a, b);
12+
}
13+
}

0 commit comments

Comments
 (0)