From e8a0e592da3e8f5cadc0c854c61b0934d10bc0a4 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 12 Oct 2011 13:31:41 -0700 Subject: [PATCH] reimplement some of the unsafe stuff which got lost - blocks inherit unsafety - remove the --check-unsafe flag - add unsafe annotations where needed to get things to compile --- src/comp/back/link.rs | 17 ++-- src/comp/driver/rustc.rs | 4 +- src/comp/driver/session.rs | 3 +- src/comp/lib/llvm.rs | 4 +- src/comp/metadata/creader.rs | 36 ++++---- src/comp/metadata/decoder.rs | 4 + src/comp/middle/gc.rs | 6 +- src/comp/middle/shape.rs | 6 +- src/comp/middle/trans_build.rs | 6 +- src/comp/middle/trans_common.rs | 86 ++++++++----------- src/comp/middle/trans_objects.rs | 4 +- src/comp/middle/typeck.rs | 36 ++++---- src/compiletest/procsrv.rs | 6 +- src/lib/aio.rs | 4 +- src/lib/dbg.rs | 6 +- src/lib/generic_os.rs | 2 +- src/lib/io.rs | 6 +- src/lib/run_program.rs | 2 +- src/lib/str.rs | 8 +- src/lib/sys.rs | 24 ++---- src/lib/task.rs | 2 +- src/lib/vec.rs | 12 ++- .../compile-fail/unsafe-fn-used-in-bind.rs | 9 ++ 23 files changed, 137 insertions(+), 156 deletions(-) create mode 100644 src/test/compile-fail/unsafe-fn-used-in-bind.rs diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs index fbf1f4b78813..4a7e238ae55d 100644 --- a/src/comp/back/link.rs +++ b/src/comp/back/link.rs @@ -34,16 +34,14 @@ tag output_type { output_type_exe; } -fn llvm_err(sess: session::session, msg: str) { - unsafe { - let buf = llvm::LLVMRustGetLastError(); - if buf == std::ptr::null() { - sess.fatal(msg); - } else { sess.fatal(msg + ": " + str::str_from_cstr(buf)); } - } +fn llvm_err(sess: session::session, msg: str) unsafe { + let buf = llvm::LLVMRustGetLastError(); + if buf == std::ptr::null() { + sess.fatal(msg); + } else { sess.fatal(msg + ": " + str::str_from_cstr(buf)); } } -fn link_intrinsics(sess: session::session, llmod: ModuleRef) unsafe { +fn link_intrinsics(sess: session::session, llmod: ModuleRef) { let path = alt filesearch::search( sess.filesearch(), bind filesearch::pick_file("intrinsics.bc", _)) { @@ -90,8 +88,7 @@ mod write { } else { stem = str::substr(output_path, 0u, dot_pos as uint); } ret stem + "." + extension; } - fn run_passes(sess: session::session, llmod: ModuleRef, output: str) - unsafe { + fn run_passes(sess: session::session, llmod: ModuleRef, output: str) { let opts = sess.get_opts(); if opts.time_llvm_passes { llvm::LLVMRustEnableTimePasses(); } link_intrinsics(sess, llmod); diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 46f8da829a63..43d138c9e1ac 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -325,7 +325,6 @@ 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 { @@ -397,8 +396,7 @@ fn build_session_options(match: getopts::match) parse_only: parse_only, no_trans: no_trans, do_gc: do_gc, - stack_growth: stack_growth, - check_unsafe: check_unsafe}; + stack_growth: stack_growth}; ret sopts; } diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs index 6ba2148e8a4c..1f3f9baab8a9 100644 --- a/src/comp/driver/session.rs +++ b/src/comp/driver/session.rs @@ -41,8 +41,7 @@ type options = parse_only: bool, no_trans: bool, do_gc: bool, - stack_growth: bool, - check_unsafe: bool}; + stack_growth: bool}; type crate_metadata = {name: str, data: [u8]}; diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs index c028c028e6b2..9562e05bed57 100644 --- a/src/comp/lib/llvm.rs +++ b/src/comp/lib/llvm.rs @@ -956,7 +956,7 @@ fn type_to_str_inner(names: type_names, outer0: [TypeRef], ty: TypeRef) -> 7 { ret "i" + std::int::str(llvm::LLVMGetIntTypeWidth(ty) as int); } - 8 unsafe { + 8 { let s = "fn("; let out_ty: TypeRef = llvm::LLVMGetReturnType(ty); let n_args: uint = llvm::LLVMCountParamTypes(ty); @@ -969,7 +969,7 @@ fn type_to_str_inner(names: type_names, outer0: [TypeRef], ty: TypeRef) -> s += type_to_str_inner(names, outer, out_ty); ret s; } - 9 unsafe { + 9 { let s: str = "{"; let n_elts: uint = llvm::LLVMCountStructElementTypes(ty); let elts: [TypeRef] = vec::init_elt::(0 as TypeRef, n_elts); diff --git a/src/comp/metadata/creader.rs b/src/comp/metadata/creader.rs index 1dd51a8b680a..fe352290d2c8 100644 --- a/src/comp/metadata/creader.rs +++ b/src/comp/metadata/creader.rs @@ -169,27 +169,25 @@ fn find_library_crate_aux(nn: {prefix: str, suffix: str}, crate_name: str, }); } -fn get_metadata_section(filename: str) -> option::t<@[u8]> { - unsafe { - let mb = str::as_buf(filename, {|buf| - llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf) - }); - if mb as int == 0 { ret option::none::<@[u8]>; } - let of = mk_object_file(mb); - let si = mk_section_iter(of.llof); - while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { - let name_buf = llvm::LLVMGetSectionName(si.llsi); - let name = str::str_from_cstr(name_buf); - if str::eq(name, x86::get_meta_sect_name()) { - let cbuf = llvm::LLVMGetSectionContents(si.llsi); - let csz = llvm::LLVMGetSectionSize(si.llsi); - let cvbuf: *u8 = std::unsafe::reinterpret_cast(cbuf); - ret option::some::<@[u8]>(@vec::unsafe::from_buf(cvbuf, csz)); - } - llvm::LLVMMoveToNextSection(si.llsi); +fn get_metadata_section(filename: str) -> option::t<@[u8]> unsafe { + let mb = str::as_buf(filename, {|buf| + llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf) + }); + if mb as int == 0 { ret option::none::<@[u8]>; } + let of = mk_object_file(mb); + let si = mk_section_iter(of.llof); + while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { + let name_buf = llvm::LLVMGetSectionName(si.llsi); + let name = str::str_from_cstr(name_buf); + if str::eq(name, x86::get_meta_sect_name()) { + let cbuf = llvm::LLVMGetSectionContents(si.llsi); + let csz = llvm::LLVMGetSectionSize(si.llsi); + let cvbuf: *u8 = std::unsafe::reinterpret_cast(cbuf); + ret option::some::<@[u8]>(@vec::unsafe::from_buf(cvbuf, csz)); } - ret option::none::<@[u8]>; + llvm::LLVMMoveToNextSection(si.llsi); } + ret option::none::<@[u8]>; } fn load_library_crate(sess: session::session, span: span, ident: ast::ident, diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index 4a103d357558..8d3f8f5d8244 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -256,6 +256,8 @@ fn family_has_type_params(fam_ch: u8) -> bool { 'u' { true } 'p' { true } 'F' { true } + 'U' { true } + 'P' { true } 'y' { true } 't' { true } 'T' { false } @@ -285,6 +287,8 @@ fn item_family_to_str(fam: u8) -> str { 'u' { ret "unsafe fn"; } 'p' { ret "pure fn"; } 'F' { ret "native fn"; } + 'U' { ret "unsafe native fn"; } + 'P' { ret "pure native fn"; } 'y' { ret "type"; } 'T' { ret "native type"; } 't' { ret "type"; } diff --git a/src/comp/middle/gc.rs b/src/comp/middle/gc.rs index 7de07b55e3b1..be5376bc2b6b 100644 --- a/src/comp/middle/gc.rs +++ b/src/comp/middle/gc.rs @@ -16,8 +16,7 @@ type ctxt = @{mutable next_tydesc_num: uint}; fn mk_ctxt() -> ctxt { ret @{mutable next_tydesc_num: 0u}; } -fn add_global(ccx: @crate_ctxt, llval: ValueRef, name: str) - -> ValueRef unsafe { +fn add_global(ccx: @crate_ctxt, llval: ValueRef, name: str) -> ValueRef { let llglobal = str::as_buf(name, {|buf| @@ -28,8 +27,7 @@ fn add_global(ccx: @crate_ctxt, llval: ValueRef, name: str) ret llglobal; } -fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> - @block_ctxt unsafe { +fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt { let bcx = cx; if !type_is_gc_relevant(bcx_tcx(cx), ty) || ty::type_has_dynamic_size(bcx_tcx(cx), ty) { diff --git a/src/comp/middle/shape.rs b/src/comp/middle/shape.rs index 17c72d6b6c21..7c54bde66b32 100644 --- a/src/comp/middle/shape.rs +++ b/src/comp/middle/shape.rs @@ -72,7 +72,7 @@ fn eq_res_info(a: res_info, b: res_info) -> bool { } fn mk_global(ccx: @crate_ctxt, name: str, llval: ValueRef, internal: bool) -> - ValueRef unsafe { + ValueRef { let llglobal = str::as_buf(name, {|buf| @@ -245,7 +245,7 @@ fn s_float(_tcx: ty_ctxt) -> u8 { ret shape_f64; // TODO: x86-64 } -fn mk_ctxt(llmod: ModuleRef) -> ctxt unsafe { +fn mk_ctxt(llmod: ModuleRef) -> ctxt { let llshapetablesty = trans_common::T_named_struct("shapes"); let llshapetables = str::as_buf("shapes", @@ -580,7 +580,7 @@ fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef { ret mk_global(ccx, "resource_shapes", C_struct(dtors), true); } -fn gen_shape_tables(ccx: @crate_ctxt) unsafe { +fn gen_shape_tables(ccx: @crate_ctxt) { let lltagstable = gen_tag_shapes(ccx); let llresourcestable = gen_resource_shapes(ccx); trans_common::set_struct_body(ccx.shape_cx.llshapetablesty, diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs index 7cf9a9c27b3f..d0b0523af937 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -492,16 +492,16 @@ fn _UndefReturn(Fn: ValueRef) -> ValueRef { } fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { + if cx.unreachable { ret _UndefReturn(Fn); } unsafe { - if cx.unreachable { ret _UndefReturn(Fn); } ret llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); } } fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { + if cx.unreachable { ret _UndefReturn(Fn); } unsafe { - if cx.unreachable { ret _UndefReturn(Fn); } let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv); @@ -511,8 +511,8 @@ fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint) -> ValueRef { + if cx.unreachable { ret _UndefReturn(Fn); } unsafe { - if cx.unreachable { ret _UndefReturn(Fn); } let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); llvm::LLVMSetInstructionCallConv(v, Conv); diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 945530d87d2a..6ed895aa6559 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -427,14 +427,12 @@ fn val_ty(v: ValueRef) -> TypeRef { ret llvm::LLVMTypeOf(v); } fn val_str(tn: type_names, v: ValueRef) -> str { ret ty_str(tn, val_ty(v)); } // Returns the nth element of the given LLVM structure type. -fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef { - unsafe { - let elt_count = llvm::LLVMCountStructElementTypes(llstructty); - assert (n < elt_count); - let elt_tys = std::vec::init_elt(T_nil(), elt_count); - llvm::LLVMGetStructElementTypes(llstructty, to_ptr(elt_tys)); - ret llvm::LLVMGetElementType(elt_tys[n]); - } +fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef unsafe { + let elt_count = llvm::LLVMCountStructElementTypes(llstructty); + assert (n < elt_count); + let elt_tys = std::vec::init_elt(T_nil(), elt_count); + llvm::LLVMGetStructElementTypes(llstructty, to_ptr(elt_tys)); + ret llvm::LLVMGetElementType(elt_tys[n]); } fn find_scope_cx(cx: @block_ctxt) -> @block_ctxt { @@ -541,10 +539,8 @@ fn T_named_struct(name: str) -> TypeRef { ret str::as_buf(name, {|buf| llvm::LLVMStructCreateNamed(c, buf) }); } -fn set_struct_body(t: TypeRef, elts: [TypeRef]) { - unsafe { - llvm::LLVMStructSetBody(t, to_ptr(elts), std::vec::len(elts), False); - } +fn set_struct_body(t: TypeRef, elts: [TypeRef]) unsafe { + llvm::LLVMStructSetBody(t, to_ptr(elts), std::vec::len(elts), False); } fn T_empty_struct() -> TypeRef { ret T_struct([]); } @@ -581,18 +577,16 @@ fn T_task() -> TypeRef { ret t; } -fn T_tydesc_field(cx: crate_ctxt, field: int) -> TypeRef { +fn T_tydesc_field(cx: crate_ctxt, field: int) -> TypeRef unsafe { // Bit of a kludge: pick the fn typeref out of the tydesc.. - unsafe { - let tydesc_elts: [TypeRef] = - std::vec::init_elt::(T_nil(), - abi::n_tydesc_fields as uint); - llvm::LLVMGetStructElementTypes(cx.tydesc_type, - to_ptr::(tydesc_elts)); - let t = llvm::LLVMGetElementType(tydesc_elts[field]); - ret t; - } + let tydesc_elts: [TypeRef] = + std::vec::init_elt::(T_nil(), + abi::n_tydesc_fields as uint); + llvm::LLVMGetStructElementTypes(cx.tydesc_type, + to_ptr::(tydesc_elts)); + let t = llvm::LLVMGetElementType(tydesc_elts[field]); + ret t; } fn T_glue_fn(cx: crate_ctxt) -> TypeRef { @@ -798,43 +792,33 @@ fn C_postr(s: str) -> ValueRef { }); } -fn C_zero_byte_arr(size: uint) -> ValueRef { - unsafe { - let i = 0u; - let elts: [ValueRef] = []; - while i < size { elts += [C_u8(0u)]; i += 1u; } - ret llvm::LLVMConstArray(T_i8(), std::vec::to_ptr(elts), - std::vec::len(elts)); - } +fn C_zero_byte_arr(size: uint) -> ValueRef unsafe { + let i = 0u; + let elts: [ValueRef] = []; + while i < size { elts += [C_u8(0u)]; i += 1u; } + ret llvm::LLVMConstArray(T_i8(), std::vec::to_ptr(elts), + std::vec::len(elts)); } -fn C_struct(elts: [ValueRef]) -> ValueRef { - unsafe { - ret llvm::LLVMConstStruct(std::vec::to_ptr(elts), std::vec::len(elts), - False); - } +fn C_struct(elts: [ValueRef]) -> ValueRef unsafe { + ret llvm::LLVMConstStruct(std::vec::to_ptr(elts), std::vec::len(elts), + False); } -fn C_named_struct(T: TypeRef, elts: [ValueRef]) -> ValueRef { - unsafe { - ret llvm::LLVMConstNamedStruct(T, std::vec::to_ptr(elts), - std::vec::len(elts)); - } +fn C_named_struct(T: TypeRef, elts: [ValueRef]) -> ValueRef unsafe { + ret llvm::LLVMConstNamedStruct(T, std::vec::to_ptr(elts), + std::vec::len(elts)); } -fn C_array(ty: TypeRef, elts: [ValueRef]) -> ValueRef { - unsafe { - ret llvm::LLVMConstArray(ty, std::vec::to_ptr(elts), - std::vec::len(elts)); - } +fn C_array(ty: TypeRef, elts: [ValueRef]) -> ValueRef unsafe { + ret llvm::LLVMConstArray(ty, std::vec::to_ptr(elts), + std::vec::len(elts)); } -fn C_bytes(bytes: [u8]) -> ValueRef { - unsafe { - ret llvm::LLVMConstString( - unsafe::reinterpret_cast(vec::to_ptr(bytes)), - vec::len(bytes), False); - } +fn C_bytes(bytes: [u8]) -> ValueRef unsafe { + ret llvm::LLVMConstString( + unsafe::reinterpret_cast(vec::to_ptr(bytes)), + vec::len(bytes), False); } fn C_shape(ccx: @crate_ctxt, bytes: [u8]) -> ValueRef { diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs index af5f4266b9eb..a2a63d88306f 100644 --- a/src/comp/middle/trans_objects.rs +++ b/src/comp/middle/trans_objects.rs @@ -569,7 +569,7 @@ fn create_backwarding_vtbl(cx: @local_ctxt, sp: span, inner_obj_ty: ty::t, // finish_vtbl: Given a vector of vtable entries, create the table in // read-only memory and return a pointer to it. fn finish_vtbl(cx: @local_ctxt, llmethods: [ValueRef], name: str) -> - ValueRef unsafe { + ValueRef { let vtbl = C_struct(llmethods); let vtbl_name = mangle_internal_name_by_path(cx.ccx, cx.path + [name]); let gvar = @@ -619,7 +619,7 @@ fn begin_fn(cx: @local_ctxt, sp: span, m: @ty::method, // returns the value returned from that call. fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method, ty_params: [ast::ty_param], outer_obj_ty: ty::t, - _additional_field_tys: [ty::t]) -> ValueRef unsafe { + _additional_field_tys: [ty::t]) -> ValueRef { let llbackwarding_fn = begin_fn(cx, sp, m, ty_params, "backwarding_fn"); let fcx = new_fn_ctxt(cx, sp, llbackwarding_fn); diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index aed017eeef56..4b0f4f7b1c10 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1524,15 +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) { - if sess.get_opts().check_unsafe { - alt f_purity { - ast::unsafe_fn. { ret; } - _ { - sess.span_err( - sp, - "unsafe operation requires unsafe function or block"); - } - } + alt f_purity { + ast::unsafe_fn. { ret; } + _ { + sess.span_err( + sp, + "unsafe operation requires unsafe function or block"); + } } } @@ -1551,15 +1549,12 @@ 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.)) | some(ast::def_native_fn(_, ast::unsafe_fn.)) { - if sess.get_opts().check_unsafe { - ccx.tcx.sess.span_err( - sp, - "safe function calls function marked unsafe"); - } + ccx.tcx.sess.span_err( + sp, + "safe function calls function marked unsafe"); } _ { } @@ -2727,13 +2722,22 @@ fn check_constraints(fcx: @fn_ctxt, cs: [@ast::constr], args: [ast::arg]) { fn check_fn(ccx: @crate_ctxt, f: ast::_fn, id: ast::node_id, old_fcx: option::t<@fn_ctxt>) { + let decl = f.decl; let body = f.body; + + // If old_fcx is some(...), this is a block fn { |x| ... }. + // In that case, the purity is inherited from the context. + let purity = alt old_fcx { + none. { decl.purity } + some(f) { assert decl.purity == ast::impure_fn; f.purity } + }; + let gather_result = gather_locals(ccx, f, id, old_fcx); let fixups: [ast::node_id] = []; let fcx: @fn_ctxt = @{ret_ty: ty::ty_fn_ret(ccx.tcx, ty::node_id_to_type(ccx.tcx, id)), - purity: decl.purity, + purity: purity, proto: f.proto, var_bindings: gather_result.var_bindings, locals: gather_result.locals, diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index 467b98d8b640..1563e3112ca1 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -70,7 +70,7 @@ fn run(handle: handle, lib_path: str, prog: str, args: [str], ret {status: status, out: output, err: errput}; } -fn writeclose(fd: int, s: option::t) unsafe { +fn writeclose(fd: int, s: option::t) { if option::is_some(s) { let writer = io::new_writer(io::fd_buf_writer(fd, option::none)); writer.write_str(option::get(s)); @@ -79,7 +79,7 @@ fn writeclose(fd: int, s: option::t) unsafe { os::libc::close(fd); } -fn readclose(fd: int) -> str unsafe { +fn readclose(fd: int) -> str { // Copied from run::program_output let file = os::fd_FILE(fd); let reader = io::new_reader(io::FILE_buf_reader(file, option::none)); @@ -92,7 +92,7 @@ fn readclose(fd: int) -> str unsafe { ret buf; } -fn worker(p: port) unsafe { +fn worker(p: port) { // FIXME (787): If we declare this inside of the while loop and then // break out of it before it's ever initialized (i.e. we don't run diff --git a/src/lib/aio.rs b/src/lib/aio.rs index 5d7430a82ecf..42f744ff865e 100644 --- a/src/lib/aio.rs +++ b/src/lib/aio.rs @@ -41,7 +41,7 @@ tag request { type ctx = chan; -fn ip_to_sbuf(ip: net::ip_addr) -> *u8 { +fn ip_to_sbuf(ip: net::ip_addr) -> *u8 unsafe { // FIXME: This is broken. We're creating a vector, getting a pointer // to its buffer, then dropping the vector. On top of that, the vector @@ -131,7 +131,7 @@ fn request_task(c: chan) { serve(ip, portnum, events, server) { task::spawn(bind server_task(ip, portnum, events, server)); } - write(socket, v, status) { + write(socket, v, status) unsafe { rustrt::aio_writedata(socket, vec::unsafe::to_ptr::(v), vec::len::(v), status); } diff --git a/src/lib/dbg.rs b/src/lib/dbg.rs index 6371eec349bf..af568ee8f0cf 100644 --- a/src/lib/dbg.rs +++ b/src/lib/dbg.rs @@ -42,9 +42,11 @@ fn debug_obj(x: T, nmethods: uint, nbytes: uint) { fn debug_fn(x: T) { rustrt::debug_fn::(x); } -fn ptr_cast(x: @T) -> @U { ret rustrt::debug_ptrcast::(x); } +unsafe fn ptr_cast(x: @T) -> @U { + ret rustrt::debug_ptrcast::(x); +} -fn refcount(a: @T) -> uint { +fn refcount(a: @T) -> uint unsafe { let p: *uint = unsafe::reinterpret_cast(a); ret *p; } diff --git a/src/lib/generic_os.rs b/src/lib/generic_os.rs index e179aa1f92c2..d1e39a2ea9f8 100644 --- a/src/lib/generic_os.rs +++ b/src/lib/generic_os.rs @@ -3,7 +3,7 @@ import str::sbuf; #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] -fn getenv(n: str) -> option::t { +fn getenv(n: str) -> option::t unsafe { let s = str::as_buf(n, {|buf| os::libc::getenv(buf) }); ret if unsafe::reinterpret_cast(s) == 0 { option::none:: diff --git a/src/lib/io.rs b/src/lib/io.rs index c2ee7ff53ca5..327e56558896 100644 --- a/src/lib/io.rs +++ b/src/lib/io.rs @@ -57,7 +57,7 @@ fn convert_whence(whence: seek_style) -> int { resource FILE_res(f: os::libc::FILE) { os::libc::fclose(f); } obj FILE_buf_reader(f: os::libc::FILE, res: option::t<@FILE_res>) { - fn read(len: uint) -> [u8] { + fn read(len: uint) -> [u8] unsafe { let buf = []; vec::reserve::(buf, len); let read = @@ -239,7 +239,7 @@ type buf_writer = }; obj FILE_writer(f: os::libc::FILE, res: option::t<@FILE_res>) { - fn write(v: [u8]) { + fn write(v: [u8]) unsafe { let len = vec::len::(v); let vbuf = vec::unsafe::to_ptr::(v); let nout = os::libc::fwrite(vbuf, len, 1u, f); @@ -254,7 +254,7 @@ obj FILE_writer(f: os::libc::FILE, res: option::t<@FILE_res>) { resource fd_res(fd: int) { os::libc::close(fd); } obj fd_buf_writer(fd: int, res: option::t<@fd_res>) { - fn write(v: [u8]) { + fn write(v: [u8]) unsafe { let len = vec::len::(v); let count = 0u; let vbuf; diff --git a/src/lib/run_program.rs b/src/lib/run_program.rs index 31bccf320374..cb36179587fa 100644 --- a/src/lib/run_program.rs +++ b/src/lib/run_program.rs @@ -21,7 +21,7 @@ fn arg_vec(prog: str, args: [@str]) -> [sbuf] { } fn spawn_process(prog: str, args: [str], in_fd: int, out_fd: int, err_fd: int) - -> int { + -> int unsafe { // Note: we have to hold on to these vector references while we hold a // pointer to their buffers let prog = prog; diff --git a/src/lib/str.rs b/src/lib/str.rs index a3c8a5486920..7a5660244223 100644 --- a/src/lib/str.rs +++ b/src/lib/str.rs @@ -426,16 +426,18 @@ type sbuf = *u8; // NB: This is intentionally unexported because it's easy to misuse (there's // no guarantee that the string is rooted). Instead, use as_buf below. -fn buf(s: str) -> sbuf { +unsafe fn buf(s: str) -> sbuf { let saddr = ptr::addr_of(s); let vaddr: *[u8] = unsafe::reinterpret_cast(saddr); let buf = vec::to_ptr(*vaddr); ret buf; } -fn as_buf(s: str, f: block(sbuf) -> T) -> T { let buf = buf(s); f(buf) } +fn as_buf(s: str, f: block(sbuf) -> T) -> T unsafe { + let buf = buf(s); f(buf) +} -fn str_from_cstr(cstr: sbuf) -> str { +unsafe fn str_from_cstr(cstr: sbuf) -> str { let res = ""; let start = cstr; let curr = start; diff --git a/src/lib/sys.rs b/src/lib/sys.rs index c366e7c4ce52..40209f9e54eb 100644 --- a/src/lib/sys.rs +++ b/src/lib/sys.rs @@ -15,39 +15,27 @@ native "rust" mod rustrt { } fn last_os_error() -> str { - //unsafe { - ret rustrt::last_os_error(); - //} + ret rustrt::last_os_error(); } fn size_of() -> uint { - //unsafe { - ret rustrt::size_of::(); - //} + ret rustrt::size_of::(); } fn align_of() -> uint { - //unsafe { - ret rustrt::align_of::(); - //} + ret rustrt::align_of::(); } fn refcount(t: @T) -> uint { - //unsafe { - ret rustrt::refcount::(t); - //} + ret rustrt::refcount::(t); } fn do_gc() -> () { - //unsafe { - ret rustrt::do_gc(); - //} + ret rustrt::do_gc(); } fn unsupervise() -> () { - //unsafe { - ret rustrt::unsupervise(); - //} + ret rustrt::unsupervise(); } // Local Variables: diff --git a/src/lib/task.rs b/src/lib/task.rs index 7a95ea49aafd..de1a749fee35 100644 --- a/src/lib/task.rs +++ b/src/lib/task.rs @@ -108,7 +108,7 @@ fn spawn_joinable(-thunk: fn()) -> joinable_task { // FIXME: make this a fn~ once those are supported. fn spawn_inner(-thunk: fn(), notify: option>) -> - task_id { + task_id unsafe { let id = rustrt::new_task(); let raw_thunk: {code: u32, env: u32} = cast(thunk); diff --git a/src/lib/vec.rs b/src/lib/vec.rs index b2d19d9ed54e..04e35e9e979b 100644 --- a/src/lib/vec.rs +++ b/src/lib/vec.rs @@ -15,9 +15,7 @@ native "rust" mod rustrt { /// Reserves space for `n` elements in the given vector. fn reserve<@T>(&v: [mutable? T], n: uint) { - //unsafe { - rustrt::vec_reserve_shared(v, n); - //} + rustrt::vec_reserve_shared(v, n); } pure fn len(v: [mutable? T]) -> uint { unchecked { rusti::vec_len(v) } } @@ -353,22 +351,22 @@ iter iter2<@T>(v: [T]) -> (uint, T) { mod unsafe { type vec_repr = {mutable fill: uint, mutable alloc: uint, data: u8}; - fn from_buf<@T>(ptr: *T, elts: uint) -> [T] { + unsafe fn from_buf<@T>(ptr: *T, elts: uint) -> [T] { ret rustrt::vec_from_buf_shared(ptr, elts); } - fn set_len<@T>(&v: [T], new_len: uint) { + unsafe fn set_len<@T>(&v: [T], new_len: uint) { let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v)); (**repr).fill = new_len * sys::size_of::(); } - fn to_ptr<@T>(v: [T]) -> *T { + unsafe fn to_ptr<@T>(v: [T]) -> *T { let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v)); ret ::unsafe::reinterpret_cast(addr_of((**repr).data)); } } -fn to_ptr<@T>(v: [T]) -> *T { ret unsafe::to_ptr(v); } +unsafe fn to_ptr<@T>(v: [T]) -> *T { ret unsafe::to_ptr(v); } // Local Variables: // mode: rust; diff --git a/src/test/compile-fail/unsafe-fn-used-in-bind.rs b/src/test/compile-fail/unsafe-fn-used-in-bind.rs new file mode 100644 index 000000000000..2622afe2e39f --- /dev/null +++ b/src/test/compile-fail/unsafe-fn-used-in-bind.rs @@ -0,0 +1,9 @@ +// -*- rust -*- +// error-pattern: unsafe functions can only be called + +unsafe fn f(x: int, y: int) -> int { ret x + y; } + +fn main() { + let x = bind f(3, _); + let y = x(4); +}