1
1
import syntax:: { visit, ast_util} ;
2
2
import syntax:: ast:: * ;
3
3
import syntax:: codemap:: span;
4
- import ty:: { kind, kind_sendable, kind_copyable, kind_noncopyable, kind_const,
5
- operators} ;
4
+ import ty:: { kind, kind_copyable, kind_noncopyable, kind_const, operators} ;
6
5
import driver:: session:: session;
7
6
import std:: map:: hashmap;
8
7
import util:: ppaux:: { ty_to_str, tys_to_str} ;
@@ -21,6 +20,7 @@ import lint::{non_implicitly_copyable_typarams,implicit_copies};
21
20
// copy: Things that can be copied.
22
21
// const: Things thare are deeply immutable. They are guaranteed never to
23
22
// change, and can be safely shared without copying between tasks.
23
+ // owned: Things that do not contain borrowed pointers.
24
24
//
25
25
// Send includes scalar types as well as classes and unique types containing
26
26
// only sendable types.
@@ -41,15 +41,21 @@ import lint::{non_implicitly_copyable_typarams,implicit_copies};
41
41
42
42
fn kind_to_str ( k : kind ) -> ~str {
43
43
let mut kinds = ~[ ] ;
44
+
44
45
if ty:: kind_lteq ( kind_const ( ) , k) {
45
46
vec:: push ( kinds, ~"const ") ;
46
47
}
48
+
47
49
if ty:: kind_can_be_copied ( k) {
48
50
vec:: push ( kinds, ~"copy") ;
49
51
}
52
+
50
53
if ty:: kind_can_be_sent ( k) {
51
54
vec:: push ( kinds, ~"send") ;
55
+ } else if ty:: kind_is_owned ( k) {
56
+ vec:: push ( kinds, ~"owned") ;
52
57
}
58
+
53
59
str:: connect ( kinds, ~" ")
54
60
}
55
61
@@ -93,8 +99,8 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
93
99
fn check_for_uniq(cx: ctx, id: node_id, fv: option<@freevar_entry>,
94
100
is_move: bool, var_t: ty::t, sp: span) {
95
101
// all captured data must be sendable, regardless of whether it is
96
- // moved in or copied in
97
- check_send(cx, var_t, sp);
102
+ // moved in or copied in. Note that send implies owned.
103
+ if ! check_send(cx, var_t, sp) { ret; }
98
104
99
105
// copied in data must be copyable, but moved in data can be anything
100
106
let is_implicit = fv.is_some();
@@ -108,6 +114,9 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
108
114
109
115
fn check_for_box(cx: ctx, id: node_id, fv: option<@freevar_entry>,
110
116
is_move: bool, var_t: ty::t, sp: span) {
117
+ // all captured data must be owned
118
+ if !check_owned(cx, var_t, sp) { ret; }
119
+
111
120
// copied in data must be copyable, but moved in data can be anything
112
121
let is_implicit = fv.is_some();
113
122
if !is_move { check_copy(cx, id, var_t, sp, is_implicit); }
@@ -422,9 +431,21 @@ fn check_copy(cx: ctx, id: node_id, ty: ty::t, sp: span,
422
431
}
423
432
}
424
433
425
- fn check_send ( cx : ctx , ty : ty:: t , sp : span ) {
434
+ fn check_send ( cx : ctx , ty : ty:: t , sp : span ) -> bool {
426
435
if !ty:: kind_can_be_sent ( ty:: type_kind ( cx. tcx , ty) ) {
427
436
cx. tcx . sess . span_err ( sp, ~"not a sendable value") ;
437
+ false
438
+ } else {
439
+ true
440
+ }
441
+ }
442
+
443
+ fn check_owned ( cx : ctx , ty : ty:: t , sp : span ) -> bool {
444
+ if !ty:: kind_is_owned ( ty:: type_kind ( cx. tcx , ty) ) {
445
+ cx. tcx . sess . span_err ( sp, ~"not an owned value") ;
446
+ false
447
+ } else {
448
+ true
428
449
}
429
450
}
430
451
0 commit comments