Skip to content

Commit 321ee8a

Browse files
nikomatsakisbrson
authored andcommitted
---
yaml --- r: 5799 b: refs/heads/master c: 81533ff h: refs/heads/master i: 5797: f53ca1a 5795: 1263a79 5791: 21d98f3 v: v3
1 parent 9c91b87 commit 321ee8a

File tree

5 files changed

+86
-2
lines changed

5 files changed

+86
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: e39db5a100b5c65f50b658362a5796ae6b2a5411
2+
refs/heads/master: 81533ff737f2d71c7518188b71fbafd73e0d1434

trunk/src/comp/driver/rustc.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import metadata::{creader, cstore};
55
import syntax::parse::{parser, token};
66
import syntax::{ast, codemap};
77
import front::attr;
8-
import middle::{trans, resolve, freevars, kind, ty, typeck};
8+
import middle::{trans, resolve, freevars, kind, ty, typeck, unsafeck};
99
import middle::tstate::ck;
1010
import syntax::print::{pp, pprust};
1111
import util::{ppaux, common, filesearch};
@@ -129,6 +129,8 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
129129
bind freevars::annotate_freevars(def_map, crate));
130130
let ty_cx = ty::mk_ctxt(sess, def_map, ext_map, ast_map, freevars);
131131
time(time_passes, "typechecking", bind typeck::check_crate(ty_cx, crate));
132+
time(time_passes, "unsafechecking",
133+
bind unsafeck::unsafeck_crate(ty_cx, crate));
132134
time(time_passes, "alt checking",
133135
bind middle::check_alt::check_crate(ty_cx, crate));
134136
if sess.get_opts().run_typestate {

trunk/src/comp/middle/unsafeck.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import syntax::ast;
2+
import syntax::visit;
3+
import std::option::some;
4+
import syntax::print::pprust::{expr_to_str, path_to_str};
5+
6+
export unsafeck_crate;
7+
8+
type unsafe_ctx = {
9+
tcx: ty::ctxt,
10+
unsafe_fn_legal: bool
11+
};
12+
13+
fn unsafeck_view_item(_vi: @ast::view_item,
14+
_ctx: unsafe_ctx,
15+
_v: visit::vt<unsafe_ctx>) {
16+
// Ignore paths that appear in use, import, etc
17+
}
18+
19+
fn unsafeck_expr(expr: @ast::expr,
20+
ctx: unsafe_ctx,
21+
v: visit::vt<unsafe_ctx>) {
22+
alt expr.node {
23+
ast::expr_path(path) {
24+
if !ctx.unsafe_fn_legal {
25+
alt ctx.tcx.def_map.find(expr.id) {
26+
some(ast::def_fn(_, ast::unsafe_fn.)) |
27+
some(ast::def_native_fn(_, ast::unsafe_fn.)) {
28+
log_err ("expr=", expr_to_str(expr));
29+
ctx.tcx.sess.span_fatal(
30+
expr.span,
31+
"unsafe functions can only be called");
32+
}
33+
34+
_ {}
35+
}
36+
}
37+
}
38+
39+
ast::expr_call(f, args) {
40+
let f_ctx = {unsafe_fn_legal: true with ctx};
41+
visit::visit_expr(f, f_ctx, v);
42+
43+
let args_ctx = {unsafe_fn_legal: false with ctx};
44+
visit::visit_exprs(args, args_ctx, v);
45+
}
46+
47+
_ {
48+
let subctx = {unsafe_fn_legal: false with ctx};
49+
visit::visit_expr(expr, subctx, v);
50+
}
51+
}
52+
}
53+
54+
fn unsafeck_crate(tcx: ty::ctxt, crate: @ast::crate) {
55+
let visit =
56+
visit::mk_vt(
57+
@{visit_expr: unsafeck_expr,
58+
visit_view_item: unsafeck_view_item
59+
with *visit::default_visitor()});
60+
let ctx = {tcx: tcx, unsafe_fn_legal: false};
61+
visit::visit_crate(*crate, ctx, visit);
62+
}
63+
64+
65+
// Local Variables:
66+
// mode: rust
67+
// fill-column: 78;
68+
// indent-tabs-mode: nil
69+
// c-basic-offset: 4
70+
// buffer-file-coding-system: utf-8-unix
71+
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
72+
// End:

trunk/src/comp/rustc.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod middle {
2525
mod ast_map;
2626
mod resolve;
2727
mod typeck;
28+
mod unsafeck;
2829
mod check_alt;
2930
mod mut;
3031
mod alias;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// -*- rust -*-
2+
// error-pattern: unsafe functions can only be called
3+
4+
unsafe fn f() { ret; }
5+
6+
fn main() {
7+
let x = f;
8+
x();
9+
}

0 commit comments

Comments
 (0)