Skip to content

Commit 0e42004

Browse files
committed
introduce an owned kind for data that contains no borrowed ptrs
1 parent d809336 commit 0e42004

25 files changed

+245
-142
lines changed

src/libsyntax/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ enum ty_param_bound {
6262
bound_copy,
6363
bound_send,
6464
bound_const,
65+
bound_owned,
6566
bound_trait(@ty),
6667
}
6768

src/libsyntax/fold.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl {
135135

136136
fn fold_ty_param_bound(tpb: ty_param_bound, fld: ast_fold) -> ty_param_bound {
137137
alt tpb {
138-
bound_copy | bound_send | bound_const { tpb }
138+
bound_copy | bound_send | bound_const | bound_owned { tpb }
139139
bound_trait(ty) { bound_trait(fld.fold_ty(ty)) }
140140
}
141141
}

src/libsyntax/parse/parser.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import dvec::{dvec, extensions};
1616
import vec::{push};
1717
import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
1818
bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
19-
bound_copy, bound_send, bound_trait, box, by_copy, by_move,
19+
bound_copy, bound_send, bound_trait, bound_owned,
20+
box, by_copy, by_move,
2021
by_mutbl_ref, by_ref, by_val, capture_clause, capture_item,
2122
carg_base, carg_ident, cdir_dir_mod, cdir_src_mod,
2223
cdir_view_item, checked_expr, claimed_expr, class_immutable,
@@ -1935,12 +1936,16 @@ class parser {
19351936
let ident = self.parse_ident();
19361937
if self.eat(token::COLON) {
19371938
while self.token != token::COMMA && self.token != token::GT {
1938-
if self.eat_keyword(~"send") { push(bounds, bound_send); }
1939-
else if self.eat_keyword(~"copy") { push(bounds, bound_copy) }
1939+
if self.eat_keyword(~"send") {
1940+
push(bounds, bound_send); }
1941+
else if self.eat_keyword(~"copy") {
1942+
push(bounds, bound_copy) }
19401943
else if self.eat_keyword(~"const") {
1941-
push(bounds, bound_const)
1942-
}
1943-
else { push(bounds, bound_trait(self.parse_ty(false))); }
1944+
push(bounds, bound_const);
1945+
} else if self.eat_keyword(~"owned") {
1946+
push(bounds, bound_owned);
1947+
} else {
1948+
push(bounds, bound_trait(self.parse_ty(false))); }
19441949
}
19451950
}
19461951
ret {ident: ident, id: self.get_id(), bounds: @bounds};

src/libsyntax/parse/token.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ fn restricted_keyword_table() -> hashmap<~str, ()> {
313313
~"if", ~"iface", ~"impl", ~"import",
314314
~"let", ~"log", ~"loop",
315315
~"mod", ~"mut",
316-
~"new",
316+
~"new", ~"owned",
317317
~"pure", ~"ret",
318318
~"true", ~"trait", ~"type",
319319
~"unchecked", ~"unsafe",

src/libsyntax/print/pprust.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,7 @@ fn print_bounds(s: ps, bounds: @~[ast::ty_param_bound]) {
13771377
ast::bound_copy { word(s.s, ~"copy"); }
13781378
ast::bound_send { word(s.s, ~"send"); }
13791379
ast::bound_const { word(s.s, ~"const"); }
1380+
ast::bound_owned { word(s.s, ~"owned"); }
13801381
ast::bound_trait(t) { print_type(s, t); }
13811382
}
13821383
}

src/libsyntax/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ fn visit_ty_params<E>(tps: ~[ty_param], e: E, v: vt<E>) {
246246
for vec::each(*tp.bounds) |bound| {
247247
alt bound {
248248
bound_trait(t) { v.visit_ty(t, e, v); }
249-
bound_copy | bound_send | bound_const { }
249+
bound_copy | bound_send | bound_const | bound_owned { }
250250
}
251251
}
252252
}

src/rustc/metadata/tydecode.rs

+1
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ fn parse_bounds(st: @pstate, conv: conv_did) -> @~[ty::param_bound] {
417417
'S' { ty::bound_send }
418418
'C' { ty::bound_copy }
419419
'K' { ty::bound_const }
420+
'O' { ty::bound_owned }
420421
'I' { ty::bound_trait(parse_ty(st, conv)) }
421422
'.' { break; }
422423
});

src/rustc/metadata/tyencode.rs

+1
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ fn enc_bounds(w: io::writer, cx: @ctxt, bs: @~[ty::param_bound]) {
350350
ty::bound_send { w.write_char('S'); }
351351
ty::bound_copy { w.write_char('C'); }
352352
ty::bound_const { w.write_char('K'); }
353+
ty::bound_owned { w.write_char('O'); }
353354
ty::bound_trait(tp) {
354355
w.write_char('I');
355356
enc_ty(w, cx, tp);

src/rustc/middle/kind.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import syntax::{visit, ast_util};
22
import syntax::ast::*;
33
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};
65
import driver::session::session;
76
import std::map::hashmap;
87
import util::ppaux::{ty_to_str, tys_to_str};
@@ -21,6 +20,7 @@ import lint::{non_implicitly_copyable_typarams,implicit_copies};
2120
// copy: Things that can be copied.
2221
// const: Things thare are deeply immutable. They are guaranteed never to
2322
// change, and can be safely shared without copying between tasks.
23+
// owned: Things that do not contain borrowed pointers.
2424
//
2525
// Send includes scalar types as well as classes and unique types containing
2626
// only sendable types.
@@ -41,15 +41,21 @@ import lint::{non_implicitly_copyable_typarams,implicit_copies};
4141

4242
fn kind_to_str(k: kind) -> ~str {
4343
let mut kinds = ~[];
44+
4445
if ty::kind_lteq(kind_const(), k) {
4546
vec::push(kinds, ~"const");
4647
}
48+
4749
if ty::kind_can_be_copied(k) {
4850
vec::push(kinds, ~"copy");
4951
}
52+
5053
if ty::kind_can_be_sent(k) {
5154
vec::push(kinds, ~"send");
55+
} else if ty::kind_is_owned(k) {
56+
vec::push(kinds, ~"owned");
5257
}
58+
5359
str::connect(kinds, ~" ")
5460
}
5561
@@ -93,8 +99,8 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
9399
fn check_for_uniq(cx: ctx, id: node_id, fv: option<@freevar_entry>,
94100
is_move: bool, var_t: ty::t, sp: span) {
95101
// 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; }
98104
99105
// copied in data must be copyable, but moved in data can be anything
100106
let is_implicit = fv.is_some();
@@ -108,6 +114,9 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
108114
109115
fn check_for_box(cx: ctx, id: node_id, fv: option<@freevar_entry>,
110116
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+
111120
// copied in data must be copyable, but moved in data can be anything
112121
let is_implicit = fv.is_some();
113122
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,
422431
}
423432
}
424433

425-
fn check_send(cx: ctx, ty: ty::t, sp: span) {
434+
fn check_send(cx: ctx, ty: ty::t, sp: span) -> bool {
426435
if !ty::kind_can_be_sent(ty::type_kind(cx.tcx, ty)) {
427436
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
428449
}
429450
}
430451

src/rustc/middle/resolve3.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import metadata::cstore::find_use_stmt_cnum;
44
import metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
55
import middle::lint::{error, ignore, level, unused_imports, warn};
66
import syntax::ast::{_mod, arm, blk, bound_const, bound_copy, bound_trait};
7+
import syntax::ast::{bound_owned};
78
import syntax::ast::{bound_send, capture_clause, class_ctor, class_dtor};
89
import syntax::ast::{class_member, class_method, crate, crate_num, decl_item};
910
import syntax::ast::{def, def_arg, def_binding, def_class, def_const, def_fn};
@@ -3181,7 +3182,7 @@ class Resolver {
31813182
for type_parameters.each |type_parameter| {
31823183
for (*type_parameter.bounds).each |bound| {
31833184
alt bound {
3184-
bound_copy | bound_send | bound_const {
3185+
bound_copy | bound_send | bound_const | bound_owned {
31853186
// Nothing to do.
31863187
}
31873188
bound_trait(interface_type) {

0 commit comments

Comments
 (0)