From 212707ce8440205d5f49b0a274caf629bf118de0 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 11 Oct 2011 14:52:38 -0700 Subject: [PATCH] make native functions markable as unsafe and incorporate that into the type check --- src/comp/metadata/decoder.rs | 4 +++- src/comp/metadata/encoder.rs | 10 ++++++++-- src/comp/middle/resolve.rs | 8 +++++--- src/comp/middle/trans.rs | 2 +- src/comp/middle/ty.rs | 2 +- src/comp/middle/typeck.rs | 5 +++-- src/comp/syntax/ast.rs | 2 +- src/comp/syntax/ast_util.rs | 2 +- src/comp/syntax/parse/parser.rs | 11 +++++++---- 9 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index ee0b7f6c758a..4a103d357558 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -178,7 +178,9 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) -> 'u' { ast::def_fn(did, ast::unsafe_fn) } 'f' { ast::def_fn(did, ast::impure_fn) } 'p' { ast::def_fn(did, ast::pure_fn) } - 'F' { ast::def_native_fn(did) } + 'U' { ast::def_native_fn(did, ast::unsafe_fn) } + 'F' { ast::def_native_fn(did, ast::impure_fn) } + 'P' { ast::def_native_fn(did, ast::pure_fn) } 'y' { ast::def_ty(did) } 'T' { ast::def_native_ty(did) } 't' { ast::def_ty(did) } diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index b67114d3d9a3..3617005a400a 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -350,9 +350,15 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer, encode_type(ecx, ebml_w, ty::mk_native(ecx.ccx.tcx, local_def(nitem.id))); } - native_item_fn(_, _, tps) { + native_item_fn(_, fn_decl, tps) { + let letter = + alt fn_decl.purity { + unsafe_fn. { 'U' } + pure_fn. { 'P' } // this is currently impossible, but hey. + impure_fn. { 'F' } + } as u8; encode_def_id(ebml_w, local_def(nitem.id)); - encode_family(ebml_w, 'F' as u8); + encode_family(ebml_w, letter); encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, nitem.id)); encode_symbol(ecx, ebml_w, nitem.id); diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index f2995f58b6c6..b9d520b66c53 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -1059,9 +1059,11 @@ fn lookup_in_mie(e: env, mie: mod_index_entry, ns: namespace) -> ret some(ast::def_native_ty(local_def(native_item.id))); } } - ast::native_item_fn(_, _, _) { + ast::native_item_fn(_, decl, _) { if ns == ns_value { - ret some(ast::def_native_fn(local_def(native_item.id))); + ret some(ast::def_native_fn( + local_def(native_item.id), + decl.purity)); } } } @@ -1163,7 +1165,7 @@ fn ns_for_def(d: def) -> namespace { ast::def_binding(_) { ns_type } ast::def_use(_) { ns_module } ast::def_native_ty(_) { ns_type } - ast::def_native_fn(_) { ns_value } + ast::def_native_fn(_, _) { ns_value } }; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4199c81123d5..ded401ae796d 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3096,7 +3096,7 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id) -> lval_maybe_callee { let ccx = bcx_ccx(cx); alt def { - ast::def_fn(did, _) | ast::def_native_fn(did) { + ast::def_fn(did, _) | ast::def_native_fn(did, _) { let tyt = ty::lookup_item_type(ccx.tcx, did); ret lval_static_fn(cx, tyt, did, id); } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 428278b41324..3a4d852f2ade 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -2602,7 +2602,7 @@ fn def_has_ty_params(def: ast::def) -> bool { ast::def_binding(_) { ret false; } ast::def_use(_) { ret false; } ast::def_native_ty(_) { ret false; } - ast::def_native_fn(_) { ret true; } + ast::def_native_fn(_, _) { ret true; } } } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 8eebe3f9949f..f848cf638f8b 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -103,7 +103,7 @@ fn ty_param_kinds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) -> ret {kinds: no_kinds, ty: typ}; } ast::def_fn(id, _) { ret ty::lookup_item_type(fcx.ccx.tcx, id); } - ast::def_native_fn(id) { ret ty::lookup_item_type(fcx.ccx.tcx, id); } + ast::def_native_fn(id, _) { ret ty::lookup_item_type(fcx.ccx.tcx, id); } ast::def_const(id) { ret ty::lookup_item_type(fcx.ccx.tcx, id); } ast::def_variant(_, vid) { ret ty::lookup_item_type(fcx.ccx.tcx, vid); } ast::def_binding(id) { @@ -1560,7 +1560,7 @@ fn require_pure_call(ccx: @crate_ctxt, caller_purity: ast::purity, "safe function calls function marked unsafe"); } } - some(ast::def_native_fn(_)) { + some(ast::def_native_fn(_, ast::unsafe_fn.)) { if sess.get_opts().check_unsafe { ccx.tcx.sess.span_fatal( sp, @@ -1893,6 +1893,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, } ast::expr_path(pth) { let defn = lookup_def(fcx, pth.span, id); + let tpt = ty_param_kinds_and_ty_for_def(fcx, expr.span, defn); if ty::def_has_ty_params(defn) { let path_tpot = instantiate_path(fcx, pth, tpt, expr.span); diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index d9b5365db5fd..a837dbdac247 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -41,7 +41,7 @@ tag def { def_binding(def_id); def_use(def_id); def_native_ty(def_id); - def_native_fn(def_id); + def_native_fn(def_id, purity); def_upvar(def_id, @def, /* writable */bool); } diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index 32c381d90901..db9cdc2f1a13 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -37,7 +37,7 @@ fn def_id_of_def(d: def) -> def_id { def_binding(id) { ret id; } def_use(id) { ret id; } def_native_ty(id) { ret id; } - def_native_fn(id) { ret id; } + def_native_fn(id, _) { ret id; } def_upvar(id, _, _) { ret id; } } } diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index ab573691720d..7a1e61f27ba0 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -1972,11 +1972,11 @@ fn parse_item_native_type(p: parser, attrs: [ast::attribute]) -> span: ast_util::mk_sp(t.lo, hi)}; } -fn parse_item_native_fn(p: parser, attrs: [ast::attribute]) -> - @ast::native_item { +fn parse_item_native_fn(p: parser, attrs: [ast::attribute], + purity: ast::purity) -> @ast::native_item { let lo = p.get_last_lo_pos(); let t = parse_fn_header(p); - let decl = parse_fn_decl(p, ast::impure_fn, ast::il_normal); + let decl = parse_fn_decl(p, purity, ast::il_normal); let link_name = none; if p.peek() == token::EQ { p.bump(); link_name = some(parse_str(p)); } let hi = p.get_hi_pos(); @@ -1993,7 +1993,10 @@ fn parse_native_item(p: parser, attrs: [ast::attribute]) -> if eat_word(p, "type") { ret parse_item_native_type(p, attrs); } else if eat_word(p, "fn") { - ret parse_item_native_fn(p, attrs); + ret parse_item_native_fn(p, attrs, ast::impure_fn); + } else if eat_word(p, "unsafe") { + expect_word(p, "fn"); + ret parse_item_native_fn(p, attrs, ast::unsafe_fn); } else { unexpected(p, p.peek()); } }