]> git.lizzy.rs Git - rust.git/commitdiff
expand purity to include unsafe
authorNiko Matsakis <niko@alum.mit.edu>
Thu, 6 Oct 2011 22:29:54 +0000 (15:29 -0700)
committerBrian Anderson <banderson@mozilla.com>
Wed, 12 Oct 2011 21:26:47 +0000 (14:26 -0700)
src/comp/middle/alias.rs
src/comp/middle/typeck.rs
src/comp/syntax/ast.rs
src/comp/syntax/parse/parser.rs

index 27021c2a20824d968dc4c37139319217675d2e04..3314fb890a2cea586157ac3d08aea29045f63ace 100644 (file)
 type scope = {bs: [binding], ret_info: ret_info};
 
 fn mk_binding(cx: ctx, id: node_id, span: span, root_var: option::t<node_id>,
-              unsafe: [unsafe_ty]) -> binding {
+              unsafe_tys: [unsafe_ty]) -> binding {
     ret @{node_id: id, span: span, root_var: root_var,
           local_id: local_id_of_node(cx, id),
-          unsafe_tys: unsafe, mutable ok: valid,
+          unsafe_tys: unsafe_tys, mutable ok: valid,
           mutable copied: not_copied};
 }
 
@@ -284,12 +284,12 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [binding] {
     }
     let j = 0u;
     for b in bindings {
-        for unsafe in b.unsafe_tys {
+        for unsafe_ty in b.unsafe_tys {
             let i = 0u;
             for arg_t: ty::arg in arg_ts {
                 let mut_alias = arg_t.mode == ast::by_mut_ref;
                 if i != j &&
-                       ty_can_unsafely_include(cx, unsafe, arg_t.ty,
+                       ty_can_unsafely_include(cx, unsafe_ty, arg_t.ty,
                                                mut_alias) &&
                        cant_copy(cx, b) {
                     cx.tcx.sess.span_err
@@ -397,24 +397,28 @@ fn check_alt(cx: ctx, input: @ast::expr, arms: [ast::arm], sc: scope,
         let new_bs = sc.bs;
         let root_var = path_def_id(cx, root.ex);
         let pat_id_map = ast_util::pat_id_map(a.pats[0]);
-        type info = {id: node_id, mutable unsafe: [unsafe_ty], span: span};
+        type info = {
+            id: node_id,
+            mutable unsafe_tys: [unsafe_ty],
+            span: span};
         let binding_info: [info] = [];
         for pat in a.pats {
             for proot in pattern_roots(cx.tcx, root.mut, pat) {
                 let canon_id = pat_id_map.get(proot.name);
                 alt vec::find({|x| x.id == canon_id}, binding_info) {
-                  some(s) { s.unsafe += unsafe_set(proot.mut); }
+                  some(s) { s.unsafe_tys += unsafe_set(proot.mut); }
                   none. {
-                      binding_info += [{id: canon_id,
-                                        mutable unsafe: unsafe_set(proot.mut),
-                                        span: proot.span}];
+                      binding_info += [
+                          {id: canon_id,
+                           mutable unsafe_tys: unsafe_set(proot.mut),
+                           span: proot.span}];
                   }
                 }
             }
         }
         for info in binding_info {
             new_bs += [mk_binding(cx, info.id, info.span, root_var,
-                                  copy info.unsafe)];
+                                  copy info.unsafe_tys)];
         }
         visit::visit_arm(a, {bs: new_bs with sc}, v);
     }
@@ -470,8 +474,8 @@ fn check_var(cx: ctx, ex: @ast::expr, p: ast::path, id: ast::node_id,
     for b in sc.bs {
         // excludes variables introduced since the alias was made
         if my_local_id < b.local_id {
-            for unsafe in b.unsafe_tys {
-                if ty_can_unsafely_include(cx, unsafe, var_t, assign) {
+            for unsafe_ty in b.unsafe_tys {
+                if ty_can_unsafely_include(cx, unsafe_ty, var_t, assign) {
                     b.ok = val_taken(ex.span, p);
                 }
             }
@@ -689,9 +693,9 @@ fn walk(tcx: ty::ctxt, mut: option::t<unsafe_ty>, pat: @ast::pat,
 fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
     -> {ex: @ast::expr, mut: option::t<unsafe_ty>} {
     let base_root = mut::expr_root(cx.tcx, ex, autoderef);
-    let unsafe = none;
+    let unsafe_ty = none;
     for d in *base_root.ds {
-        if d.mut { unsafe = some(contains(d.outer_t)); break; }
+        if d.mut { unsafe_ty = some(contains(d.outer_t)); break; }
     }
     if is_none(path_def_id(cx, base_root.ex)) {
         alt base_root.ex.node {
@@ -703,10 +707,10 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
                 let arg_root = expr_root(cx, arg, false);
                 if mut {
                     let ret_ty = ty::expr_ty(cx.tcx, base_root.ex);
-                    unsafe = some(mut_contains(ret_ty));
+                    unsafe_ty = some(mut_contains(ret_ty));
                 }
-                if !is_none(arg_root.mut) { unsafe = arg_root.mut; }
-                ret {ex: arg_root.ex, mut: unsafe};
+                if !is_none(arg_root.mut) { unsafe_ty = arg_root.mut; }
+                ret {ex: arg_root.ex, mut: unsafe_ty};
               }
               _ {}
             }
@@ -714,7 +718,7 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
           _ {}
         }
     }
-    ret {ex: base_root.ex, mut: unsafe};
+    ret {ex: base_root.ex, mut: unsafe_ty};
 }
 
 fn unsafe_set(from: option::t<unsafe_ty>) -> [unsafe_ty] {
index 695000f7cf93f6585d39742d4c2dc215fac3575b..ee25c59a7892e462f698bf70ad7ff9c0a61f7b10 100644 (file)
@@ -1525,6 +1525,7 @@ fn matches(name: str, f: ty::field) -> bool {
 
 fn require_impure(sess: session::session, f_purity: ast::purity, sp: span) {
     alt f_purity {
+      ast::unsafe_fn. { ret; }
       ast::impure_fn. { ret; }
       ast::pure_fn. {
         sess.span_fatal(sp, "Found impure expression in pure function decl");
index a5c6e3ebd5c54f862dfc19ccbf659cdd62bfb9a9..36791c10cb27863621f299a9cbfe1bb57387243c 100644 (file)
 
 tag purity {
     pure_fn; // declared with "pure fn"
+    unsafe_fn; // declared with "unsafe fn"
     impure_fn; // declared with "fn"
 }
 
index c359cc843cc19a8fec067369fb234191ad7d6028..5a4c5d78772adbb9f4f39d38bfb2a4f3334b0730 100644 (file)
@@ -165,6 +165,7 @@ fn bad_expr_word_table() -> hashmap<str, ()> {
     words.insert("fn", ());
     words.insert("lambda", ());
     words.insert("pure", ());
+    words.insert("unsafe", ());
     words.insert("iter", ());
     words.insert("block", ());
     words.insert("import", ());
@@ -2153,6 +2154,10 @@ fn parse_item(p: parser, attrs: [ast::attribute]) -> option::t<@ast::item> {
         let proto = parse_fn_proto(p);
         ret some(parse_item_fn_or_iter(p, ast::pure_fn, proto, attrs,
                                        ast::il_normal));
+    } else if eat_word(p, "unsafe") {
+        expect_word(p, "fn");
+        ret some(parse_item_fn_or_iter(p, ast::unsafe_fn, ast::proto_fn,
+                                       attrs, ast::il_normal));
     } else if eat_word(p, "iter") {
         ret some(parse_item_fn_or_iter(p, ast::impure_fn, ast::proto_iter,
                                        attrs, ast::il_normal));