diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 4dc58c04fe5a..be09a5907415 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -264,6 +264,7 @@ options: --test build test harness --gc garbage collect shared data (experimental/temporary) --stack-growth perform stack checks (experimental) + --check-unsafe disallow unsafe actions in non-unsafe functions (temporary option) "); } @@ -322,6 +323,7 @@ fn build_session_options(match: getopts::match) let parse_only = opt_present(match, "parse-only"); let no_trans = opt_present(match, "no-trans"); + let check_unsafe = opt_present(match, "check-unsafe"); let output_type = if parse_only || no_trans { @@ -393,7 +395,8 @@ fn build_session_options(match: getopts::match) parse_only: parse_only, no_trans: no_trans, do_gc: do_gc, - stack_growth: stack_growth}; + stack_growth: stack_growth, + check_unsafe: check_unsafe}; ret sopts; } @@ -432,7 +435,7 @@ fn opts() -> [getopts::opt] { optflag("no-typestate"), optflag("noverify"), optmulti("cfg"), optflag("test"), optflag("lib"), optflag("static"), optflag("gc"), - optflag("stack-growth")]; + optflag("stack-growth"), optflag("check-unsafe")]; } fn main(args: [str]) { diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs index 1f3f9baab8a9..6ba2148e8a4c 100644 --- a/src/comp/driver/session.rs +++ b/src/comp/driver/session.rs @@ -41,7 +41,8 @@ type options = parse_only: bool, no_trans: bool, do_gc: bool, - stack_growth: bool}; + stack_growth: bool, + check_unsafe: bool}; type crate_metadata = {name: str, data: [u8]}; diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index ec7c2537874e..26dcb5074da0 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1524,11 +1524,13 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat, } fn require_unsafe(sess: session::session, f_purity: ast::purity, sp: span) { - alt f_purity { - ast::unsafe_fn. { ret; } - _ { - sess.span_fatal(sp, "Found unsafe expression in safe function decl"); - } + if sess.get_opts().check_unsafe { + alt f_purity { + ast::unsafe_fn. { ret; } + _ { + sess.span_fatal(sp, "Found unsafe expression in safe function decl"); + } + } } } @@ -1547,17 +1549,22 @@ fn require_pure_call(ccx: @crate_ctxt, caller_purity: ast::purity, alt caller_purity { ast::unsafe_fn. { ret; } ast::impure_fn. { + let sess = ccx.tcx.sess; alt ccx.tcx.def_map.find(callee.id) { some(ast::def_fn(_, ast::unsafe_fn.)) { - ccx.tcx.sess.span_fatal - (sp, "safe function calls function marked unsafe"); + if sess.get_opts().check_unsafe { + ccx.tcx.sess.span_fatal( + sp, + "safe function calls function marked unsafe"); + } } - /* Temporarily disable until unsafe blocks parse! some(ast::def_native_fn(_)) { - ccx.tcx.sess.span_fatal - (sp, "native functions can only be invoked from unsafe code"); + if sess.get_opts().check_unsafe { + ccx.tcx.sess.span_fatal( + sp, + "native functions can only be invoked from unsafe code"); + } } - */ _ { } }