Skip to content

Commit facb5c0

Browse files
committed
Enforce rule that classes with dtors aren't copyable
The test for this is copy-a-resource.
1 parent b67f8e3 commit facb5c0

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

src/rustc/middle/ty.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export field_idx;
4545
export get_field;
4646
export get_fields;
4747
export get_element_type;
48+
export has_dtor;
4849
export is_binopable;
4950
export is_pred_ty;
5051
export lookup_class_field, lookup_class_fields;
@@ -1288,7 +1289,7 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
12881289

12891290
enum kind { kind_(u32) }
12901291

1291-
// *ALL* implicity copiable things must be copiable
1292+
// *ALL* implicitly copiable things must be copiable
12921293
const KIND_MASK_COPY : u32 = 0b00000000000000000000000000000001u32;
12931294
const KIND_MASK_SEND : u32 = 0b00000000000000000000000000000010u32;
12941295
const KIND_MASK_CONST : u32 = 0b00000000000000000000000000000100u32;
@@ -1495,15 +1496,20 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
14951496
}
14961497
lowest
14971498
}
1498-
// FIXME: (tjc) there are rules about when classes are copyable/
1499-
// sendable, but I'm just treating them like records (#1726)
15001499
ty_class(did, substs) {
1500+
// Classes are sendable if all their fields are sendable,
1501+
// likewise for copyable...
15011502
// also factor out this code, copied from the records case
15021503
let mut lowest = kind_top();
15031504
let flds = class_items_as_fields(cx, did, substs);
15041505
for flds.each {|f|
15051506
lowest = lower_kind(lowest, mutable_type_kind(cx, f.mt));
15061507
}
1508+
// ...but classes with dtors are never copyable (they can be
1509+
// sendable)
1510+
if ty::has_dtor(cx, did) {
1511+
lowest = lower_kind(lowest, kind_noncopyable());
1512+
}
15071513
lowest
15081514
}
15091515
// Tuples lower to the lowest of their members.
@@ -2562,6 +2568,10 @@ fn ty_dtor(cx: ctxt, class_id: def_id) -> option<def_id> {
25622568
}
25632569
}
25642570

2571+
fn has_dtor(cx: ctxt, class_id: def_id) -> bool {
2572+
option::is_some(ty_dtor(cx, class_id))
2573+
}
2574+
25652575
fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
25662576
if id.crate != ast::local_crate {
25672577
csearch::get_item_path(cx, id)
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// error-pattern: copying a noncopyable value
22

3-
resource foo(i: int) { }
3+
class foo {
4+
let i: int;
5+
new(i:int) { self.i = i; }
6+
drop {}
7+
}
48

59
fn main() { let x <- foo(10); let y = x; log(error, x); }

0 commit comments

Comments
 (0)