Skip to content

Commit 29584cc

Browse files
nikomatsakisbrson
authored andcommitted
Extend the unchecked block stuff to allow unsafe blocks as well.
1 parent 58b8e88 commit 29584cc

File tree

12 files changed

+114
-35
lines changed

12 files changed

+114
-35
lines changed

src/comp/front/test.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ fn mk_tests(cx: test_ctxt) -> @ast::item {
184184
let test_descs = mk_test_desc_vec(cx);
185185

186186
let body_: ast::blk_ =
187-
checked_blk([], option::some(test_descs), cx.next_node_id());
187+
checked_block([], option::some(test_descs), cx.next_node_id());
188188
let body = nospan(body_);
189189

190190
let fn_ = {decl: decl, proto: proto, body: body};
@@ -303,7 +303,8 @@ fn mk_main(cx: test_ctxt) -> @ast::item {
303303
let test_main_call_expr = mk_test_main_call(cx);
304304

305305
let body_: ast::blk_ =
306-
checked_blk([], option::some(test_main_call_expr), cx.next_node_id());
306+
checked_block([], option::some(test_main_call_expr),
307+
cx.next_node_id());
307308
let body = {node: body_, span: dummy_sp()};
308309

309310
let fn_ = {decl: decl, proto: proto, body: body};

src/comp/metadata/decoder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
175175
let def =
176176
alt fam_ch as char {
177177
'c' { ast::def_const(did) }
178+
'u' { ast::def_fn(did, ast::unsafe_fn) }
178179
'f' { ast::def_fn(did, ast::impure_fn) }
179180
'p' { ast::def_fn(did, ast::pure_fn) }
180181
'F' { ast::def_native_fn(did) }

src/comp/metadata/encoder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
252252
encode_def_id(ebml_w, local_def(item.id));
253253
encode_family(ebml_w,
254254
alt fd.decl.purity {
255+
unsafe_fn. { 'u' }
255256
pure_fn. { 'p' }
256257
impure_fn. { 'f' }
257258
} as u8);

src/comp/middle/trans.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4380,11 +4380,11 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
43804380
assert dest == ignore;
43814381
ret trans_check_expr(bcx, a, "Assertion");
43824382
}
4383-
ast::expr_check(ast::checked., a) {
4383+
ast::expr_check(ast::checked_expr., a) {
43844384
assert dest == ignore;
43854385
ret trans_check_expr(bcx, a, "Predicate");
43864386
}
4387-
ast::expr_check(ast::unchecked., a) {
4387+
ast::expr_check(ast::claimed_expr., a) {
43884388
assert dest == ignore;
43894389
/* Claims are turned on and off by a global variable
43904390
that the RTS sets. This case generates code to

src/comp/middle/typeck.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,15 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat,
15231523
}
15241524
}
15251525

1526+
fn require_unsafe(sess: session::session, f_purity: ast::purity, sp: span) {
1527+
alt f_purity {
1528+
ast::unsafe_fn. { ret; }
1529+
_ {
1530+
sess.span_fatal(sp, "Found unsafe expression in safe function decl");
1531+
}
1532+
}
1533+
}
1534+
15261535
fn require_impure(sess: session::session, f_purity: ast::purity, sp: span) {
15271536
alt f_purity {
15281537
ast::unsafe_fn. { ret; }
@@ -1536,7 +1545,22 @@ fn require_impure(sess: session::session, f_purity: ast::purity, sp: span) {
15361545
fn require_pure_call(ccx: @crate_ctxt, caller_purity: ast::purity,
15371546
callee: @ast::expr, sp: span) {
15381547
alt caller_purity {
1539-
ast::impure_fn. { ret; }
1548+
ast::unsafe_fn. { ret; }
1549+
ast::impure_fn. {
1550+
alt ccx.tcx.def_map.find(callee.id) {
1551+
some(ast::def_fn(_, ast::unsafe_fn.)) {
1552+
ccx.tcx.sess.span_fatal
1553+
(sp, "safe function calls function marked unsafe");
1554+
}
1555+
//some(ast::def_native_fn(_)) {
1556+
// ccx.tcx.sess.span_fatal
1557+
// (sp, "native functions can only be invoked from unsafe code");
1558+
//}
1559+
_ {
1560+
}
1561+
}
1562+
ret;
1563+
}
15401564
ast::pure_fn. {
15411565
alt ccx.tcx.def_map.find(callee.id) {
15421566
some(ast::def_fn(_, ast::pure_fn.)) { ret; }
@@ -2066,8 +2090,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
20662090
// If this is an unchecked block, turn off purity-checking
20672091
let fcx_for_block =
20682092
alt b.node.rules {
2069-
ast::unchecked. { @{purity: ast::impure_fn with *fcx} }
2070-
_ { fcx }
2093+
ast::unchecked_blk. { @{purity: ast::impure_fn with *fcx} }
2094+
ast::unsafe_blk. { @{purity: ast::unsafe_fn with *fcx} }
2095+
ast::checked_blk. { fcx }
20712096
};
20722097
bot = check_block(fcx_for_block, b);
20732098
let typ =

src/comp/syntax/ast.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ tag meta_item_ {
7878
type blk = spanned<blk_>;
7979

8080
type blk_ =
81-
{stmts: [@stmt], expr: option::t<@expr>, id: node_id, rules: check_mode};
81+
{stmts: [@stmt], expr: option::t<@expr>, id: node_id,
82+
rules: blk_check_mode};
8283

8384
type pat = {id: node_id, node: pat_, span: span};
8485

@@ -173,7 +174,9 @@ type field_ = {mut: mutability, ident: ident, expr: @expr};
173174

174175
type field = spanned<field_>;
175176

176-
tag check_mode { checked; unchecked; }
177+
tag blk_check_mode { checked_blk; unchecked_blk; unsafe_blk; }
178+
179+
tag expr_check_mode { claimed_expr; checked_expr; }
177180

178181
type expr = {id: node_id, node: expr_, span: span};
179182

@@ -222,7 +225,7 @@ tag expr_ {
222225
expr_assert(@expr);
223226

224227
/* preds that typestate is aware of */
225-
expr_check(check_mode, @expr);
228+
expr_check(expr_check_mode, @expr);
226229

227230
/* FIXME Would be nice if expr_check desugared
228231
to expr_if_check. */

src/comp/syntax/ast_util.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,13 @@ fn eq_ty(&&a: @ty, &&b: @ty) -> bool { ret std::box::ptr_eq(a, b); }
185185
fn hash_ty(&&t: @ty) -> uint { ret t.span.lo << 16u + t.span.hi; }
186186

187187
fn block_from_expr(e: @expr) -> blk {
188-
let blk_ = checked_blk([], option::some::<@expr>(e), e.id);
188+
let blk_ = checked_block([], option::some::<@expr>(e), e.id);
189189
ret {node: blk_, span: e.span};
190190
}
191191

192-
fn checked_blk(stmts1: [@stmt], expr1: option::t<@expr>, id1: node_id) ->
192+
fn checked_block(stmts1: [@stmt], expr1: option::t<@expr>, id1: node_id) ->
193193
blk_ {
194-
ret {stmts: stmts1, expr: expr1, id: id1, rules: checked};
194+
ret {stmts: stmts1, expr: expr1, id: id1, rules: checked_blk};
195195
}
196196

197197
fn obj_field_from_anon_obj_field(f: anon_obj_field) -> obj_field {

src/comp/syntax/parse/parser.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
828828
p.peek() == token::OROR {
829829
ret parse_fn_block_expr(p);
830830
} else {
831-
let blk = parse_block_tail(p, lo, ast::checked);
831+
let blk = parse_block_tail(p, lo, ast::checked_blk);
832832
ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
833833
}
834834
} else if eat_word(p, "if") {
@@ -853,9 +853,9 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
853853
} else if eat_word(p, "lambda") {
854854
ret parse_fn_expr(p, ast::proto_closure);
855855
} else if eat_word(p, "unchecked") {
856-
expect(p, token::LBRACE);
857-
let blk = parse_block_tail(p, lo, ast::unchecked);
858-
ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
856+
ret parse_block_expr(p, lo, ast::unchecked_blk);
857+
} else if eat_word(p, "unsafe") {
858+
ret parse_block_expr(p, lo, ast::unsafe_blk);
859859
} else if p.peek() == token::LBRACKET {
860860
p.bump();
861861
let mut = parse_mutability(p);
@@ -872,7 +872,8 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
872872
ret mk_mac_expr(p, lo, p.get_hi_pos(), ast::mac_embed_type(ty));
873873
} else if p.peek() == token::POUND_LBRACE {
874874
p.bump();
875-
let blk = ast::mac_embed_block(parse_block_tail(p, lo, ast::checked));
875+
let blk = ast::mac_embed_block(
876+
parse_block_tail(p, lo, ast::checked_blk));
876877
ret mk_mac_expr(p, lo, p.get_hi_pos(), blk);
877878
} else if p.peek() == token::ELLIPSIS {
878879
p.bump();
@@ -948,15 +949,15 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
948949

949950
let e = parse_expr(p);
950951
hi = e.span.hi;
951-
ex = ast::expr_check(ast::checked, e);
952+
ex = ast::expr_check(ast::checked_expr, e);
952953
} else if eat_word(p, "claim") {
953954
/* Same rules as check, except that if check-claims
954955
is enabled (a command-line flag), then the parser turns
955956
claims into check */
956957

957958
let e = parse_expr(p);
958959
hi = e.span.hi;
959-
ex = ast::expr_check(ast::unchecked, e);
960+
ex = ast::expr_check(ast::claimed_expr, e);
960961
} else if eat_word(p, "ret") {
961962
if can_begin_expr(p.peek()) {
962963
let e = parse_expr(p);
@@ -1014,6 +1015,14 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
10141015
ret mk_expr(p, lo, hi, ex);
10151016
}
10161017

1018+
fn parse_block_expr(p: parser,
1019+
lo: uint,
1020+
blk_mode: ast::blk_check_mode) -> @ast::expr {
1021+
expect(p, token::LBRACE);
1022+
let blk = parse_block_tail(p, lo, blk_mode);
1023+
ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
1024+
}
1025+
10171026
fn parse_syntax_ext(p: parser) -> @ast::expr {
10181027
let lo = p.get_lo_pos();
10191028
expect(p, token::POUND);
@@ -1311,7 +1320,7 @@ fn parse_fn_expr(p: parser, proto: ast::proto) -> @ast::expr {
13111320
fn parse_fn_block_expr(p: parser) -> @ast::expr {
13121321
let lo = p.get_last_lo_pos();
13131322
let decl = parse_fn_block_decl(p);
1314-
let body = parse_block_tail(p, lo, ast::checked);
1323+
let body = parse_block_tail(p, lo, ast::checked_blk);
13151324
let _fn = {decl: decl, proto: ast::proto_block, body: body};
13161325
ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn));
13171326
}
@@ -1675,10 +1684,12 @@ fn stmt_ends_with_semi(stmt: ast::stmt) -> bool {
16751684
fn parse_block(p: parser) -> ast::blk {
16761685
let lo = p.get_lo_pos();
16771686
if eat_word(p, "unchecked") {
1678-
be parse_block_tail(p, lo, ast::unchecked);
1687+
be parse_block_tail(p, lo, ast::unchecked_blk);
1688+
} else if eat_word(p, "unsafe") {
1689+
be parse_block_tail(p, lo, ast::unsafe_blk);
16791690
} else {
16801691
expect(p, token::LBRACE);
1681-
be parse_block_tail(p, lo, ast::checked);
1692+
be parse_block_tail(p, lo, ast::checked_blk);
16821693
}
16831694
}
16841695

@@ -1695,7 +1706,7 @@ fn parse_block_no_value(p: parser) -> ast::blk {
16951706
// I guess that also means "already parsed the 'impure'" if
16961707
// necessary, and this should take a qualifier.
16971708
// some blocks start with "#{"...
1698-
fn parse_block_tail(p: parser, lo: uint, s: ast::check_mode) -> ast::blk {
1709+
fn parse_block_tail(p: parser, lo: uint, s: ast::blk_check_mode) -> ast::blk {
16991710
let stmts: [@ast::stmt] = [];
17001711
let expr: option::t<@ast::expr> = none;
17011712
while p.peek() != token::RBRACE {

src/comp/syntax/print/pprust.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,11 @@ tag embed_type { block_macro; block_block_fn; block_normal; }
572572

573573
fn print_possibly_embedded_block(s: ps, blk: ast::blk, embedded: embed_type,
574574
indented: uint) {
575-
alt blk.node.rules { ast::unchecked. { word(s.s, "unchecked"); } _ { } }
575+
alt blk.node.rules {
576+
ast::unchecked_blk. { word(s.s, "unchecked"); }
577+
ast::unsafe_blk. { word(s.s, "unsafe"); }
578+
ast::checked_blk. { }
579+
}
576580

577581
maybe_print_comment(s, blk.span.lo);
578582
let ann_node = node_block(s, blk);
@@ -934,8 +938,8 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
934938
}
935939
ast::expr_check(m, expr) {
936940
alt m {
937-
ast::unchecked. { word_nbsp(s, "claim"); }
938-
ast::checked. { word_nbsp(s, "check"); }
941+
ast::claimed_expr. { word_nbsp(s, "claim"); }
942+
ast::checked_expr. { word_nbsp(s, "check"); }
939943
}
940944
popen(s);
941945
print_expr(s, expr);

src/lib/io.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ obj fd_buf_writer(fd: int, res: option::t<@fd_res>) {
263263
let nout = os::libc::write(fd, vbuf, len);
264264
if nout < 0 {
265265
log_err "error dumping buffer";
266-
log_err sys::rustrt::last_os_error();
266+
log_err sys::last_os_error();
267267
fail;
268268
}
269269
count += nout as uint;
@@ -299,7 +299,7 @@ fn file_buf_writer(path: str, flags: [fileflag]) -> buf_writer {
299299
});
300300
if fd < 0 {
301301
log_err "error opening file for writing";
302-
log_err sys::rustrt::last_os_error();
302+
log_err sys::last_os_error();
303303
fail;
304304
}
305305
ret fd_buf_writer(fd, option::some(@fd_res(fd)));

src/lib/sys.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11

2-
import rustrt::size_of;
3-
4-
export rustrt;
5-
export size_of;
2+
//export rustrt;
3+
//export size_of;
64

75
native "rust" mod rustrt {
8-
96
// Explicitly re-export native stuff we want to be made
107
// available outside this crate. Otherwise it's
118
// visible-in-crate, but not re-exported.
@@ -17,6 +14,42 @@ native "rust" mod rustrt {
1714
fn unsupervise();
1815
}
1916

17+
fn last_os_error() -> str {
18+
//unsafe {
19+
ret rustrt::last_os_error();
20+
//}
21+
}
22+
23+
fn size_of<T>() -> uint {
24+
//unsafe {
25+
ret rustrt::size_of::<T>();
26+
//}
27+
}
28+
29+
fn align_of<T>() -> uint {
30+
//unsafe {
31+
ret rustrt::align_of::<T>();
32+
//}
33+
}
34+
35+
fn refcount<T>(t: @T) -> uint {
36+
//unsafe {
37+
ret rustrt::refcount::<T>(t);
38+
//}
39+
}
40+
41+
fn do_gc() -> () {
42+
//unsafe {
43+
ret rustrt::do_gc();
44+
//}
45+
}
46+
47+
fn unsupervise() -> () {
48+
//unsafe {
49+
ret rustrt::unsupervise();
50+
//}
51+
}
52+
2053
// Local Variables:
2154
// mode: rust;
2255
// fill-column: 78;

src/lib/uint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ iter range(lo: uint, hi: uint) -> uint {
3232
}
3333

3434
fn next_power_of_two(n: uint) -> uint {
35-
let halfbits: uint = sys::rustrt::size_of::<uint>() * 4u;
35+
let halfbits: uint = sys::size_of::<uint>() * 4u;
3636
let tmp: uint = n - 1u;
3737
let shift: uint = 1u;
3838
while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }

0 commit comments

Comments
 (0)