about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-08-10 18:14:27 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-08-10 18:14:55 -0700
commit7634e2911b6cedd7d06bbfd716922c4a750b47ae (patch)
treedd0468a750ab25dc63ba6e8c3e99d5df7fcc3dfd /src/rustc
parent1b32b13c720af3ee654bb72c705909e29eb31a78 (diff)
Revert "rustc: Make function types have vstores in them"
This reverts commit 0101125a962abae18525d6014cd26ad10bbb96e6.
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/metadata/tydecode.rs14
-rw-r--r--src/rustc/metadata/tyencode.rs15
-rw-r--r--src/rustc/middle/block_use.rs2
-rw-r--r--src/rustc/middle/borrowck/check_loans.rs5
-rw-r--r--src/rustc/middle/capture.rs12
-rw-r--r--src/rustc/middle/check_loop.rs3
-rw-r--r--src/rustc/middle/kind.rs10
-rw-r--r--src/rustc/middle/mem_categorization.rs8
-rw-r--r--src/rustc/middle/trans/base.rs10
-rw-r--r--src/rustc/middle/trans/closure.rs33
-rw-r--r--src/rustc/middle/trans/foreign.rs2
-rw-r--r--src/rustc/middle/trans/reflect.rs10
-rw-r--r--src/rustc/middle/trans/shape.rs22
-rw-r--r--src/rustc/middle/trans/type_use.rs7
-rw-r--r--src/rustc/middle/ty.rs65
-rw-r--r--src/rustc/middle/typeck.rs2
-rw-r--r--src/rustc/middle/typeck/astconv.rs4
-rw-r--r--src/rustc/middle/typeck/check.rs49
-rw-r--r--src/rustc/middle/typeck/check/method.rs6
-rw-r--r--src/rustc/middle/typeck/collect.rs7
-rw-r--r--src/rustc/middle/typeck/infer.rs53
-rw-r--r--src/rustc/util/ppaux.rs12
22 files changed, 114 insertions, 237 deletions
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs
index 80c64430ec3..e66d0cef71b 100644
--- a/src/rustc/metadata/tydecode.rs
+++ b/src/rustc/metadata/tydecode.rs
@@ -85,11 +85,13 @@ fn parse_ty_rust_fn(st: @pstate, conv: conv_did) -> ty::t {
     return ty::mk_fn(st.tcx, parse_ty_fn(st, conv));
 }
 
-fn parse_proto(st: @pstate) -> ty::fn_proto {
-    match next(st) {
-        'n' => ty::proto_bare,
-        'v' => ty::proto_vstore(parse_vstore(st)),
-        c => fail ~"illegal proto type kind " + str::from_char(c)
+fn parse_proto(c: char) -> ast::proto {
+    match c {
+      '~' => ast::proto_uniq,
+      '@' => ast::proto_box,
+      '&' => ast::proto_block,
+      'n' => ast::proto_bare,
+      _ => fail ~"illegal fn type kind " + str::from_char(c)
     }
 }
 
@@ -358,7 +360,7 @@ fn parse_purity(c: char) -> purity {
 }
 
 fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
-    let proto = parse_proto(st);
+    let proto = parse_proto(next(st));
     let purity = parse_purity(next(st));
     let bounds = parse_bounds(st, conv);
     assert (next(st) == '[');
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index 30b2a21167a..9e67157b181 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -306,15 +306,12 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
       }
     }
 }
-
-fn enc_proto(w: io::writer, cx: @ctxt, proto: ty::fn_proto) {
-    w.write_str(&"f");
+fn enc_proto(w: io::writer, proto: proto) {
     match proto {
-        ty::proto_bare => w.write_str(&"n"),
-        ty::proto_vstore(vstore) => {
-            w.write_str(&"v");
-            enc_vstore(w, cx, vstore);
-        }
+      proto_uniq => w.write_str(&"f~"),
+      proto_box => w.write_str(&"f@"),
+      proto_block => w.write_str(~"f&"),
+      proto_bare => w.write_str(&"fn")
     }
 }
 
@@ -338,7 +335,7 @@ fn enc_purity(w: io::writer, p: purity) {
 }
 
 fn enc_ty_fn(w: io::writer, cx: @ctxt, ft: ty::fn_ty) {
-    enc_proto(w, cx, ft.proto);
+    enc_proto(w, ft.proto);
     enc_purity(w, ft.purity);
     enc_bounds(w, cx, ft.bounds);
     w.write_char('[');
diff --git a/src/rustc/middle/block_use.rs b/src/rustc/middle/block_use.rs
index bb33b8c92a8..2896ad32d6a 100644
--- a/src/rustc/middle/block_use.rs
+++ b/src/rustc/middle/block_use.rs
@@ -14,7 +14,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
 fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
     if !cx.allow_block {
         match ty::get(ty::expr_ty(cx.tcx, ex)).struct {
-          ty::ty_fn({proto: p, _}) if ty::is_blockish(p) => {
+          ty::ty_fn({proto: p, _}) if is_blockish(p) => {
             cx.tcx.sess.span_err(ex.span,
                ~"expressions with stack closure type \
                 can only appear in callee or (by-ref) argument position");
diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs
index 4c3ee9eb4dd..301c78aa109 100644
--- a/src/rustc/middle/borrowck/check_loans.rs
+++ b/src/rustc/middle/borrowck/check_loans.rs
@@ -218,7 +218,10 @@ impl check_loan_ctxt {
     fn is_stack_closure(id: ast::node_id) -> bool {
         let fn_ty = ty::node_id_to_type(self.tcx(), id);
         let proto = ty::ty_fn_proto(fn_ty);
-        return ty::is_blockish(proto);
+        match proto {
+          ast::proto_block => true,
+          ast::proto_bare | ast::proto_uniq | ast::proto_box => false
+        }
     }
 
     fn is_allowed_pure_arg(expr: @ast::expr) -> bool {
diff --git a/src/rustc/middle/capture.rs b/src/rustc/middle/capture.rs
index b45064db88d..266c31b2805 100644
--- a/src/rustc/middle/capture.rs
+++ b/src/rustc/middle/capture.rs
@@ -59,7 +59,7 @@ fn check_capture_clause(tcx: ty::ctxt,
 
 fn compute_capture_vars(tcx: ty::ctxt,
                         fn_expr_id: ast::node_id,
-                        fn_proto: ty::fn_proto,
+                        fn_proto: ast::proto,
                         cap_clause: ast::capture_clause) -> ~[capture_var] {
     let freevars = freevars::get_freevars(tcx, fn_expr_id);
     let cap_map = map::int_hash();
@@ -101,12 +101,10 @@ fn compute_capture_vars(tcx: ty::ctxt,
     // now go through anything that is referenced but was not explicitly
     // named and add that
 
-    let implicit_mode;
-    if ty::is_blockish(fn_proto) {
-        implicit_mode = cap_ref;
-    } else {
-        implicit_mode = cap_copy;
-    }
+    let implicit_mode = match fn_proto {
+      ast::proto_block => cap_ref,
+      ast::proto_bare | ast::proto_box | ast::proto_uniq => cap_copy
+    };
 
     do vec::iter(*freevars) |fvar| {
         let fvar_def_id = ast_util::def_id_of_def(fvar.def).node;
diff --git a/src/rustc/middle/check_loop.rs b/src/rustc/middle/check_loop.rs
index a105ce68529..dad51ed48b4 100644
--- a/src/rustc/middle/check_loop.rs
+++ b/src/rustc/middle/check_loop.rs
@@ -25,8 +25,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
                 v.visit_block(b, {in_loop: false, can_ret: false}, v);
               }
               expr_loop_body(@{node: expr_fn_block(_, b, _), _}) => {
-                let blk = ty::is_blockish(ty::ty_fn_proto(ty::expr_ty(tcx,
-                                                                      e)));
+                let blk = is_blockish(ty::ty_fn_proto(ty::expr_ty(tcx, e)));
                 v.visit_block(b, {in_loop: true, can_ret: blk}, v);
               }
               expr_break => {
diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs
index 9968318292c..61d9938e388 100644
--- a/src/rustc/middle/kind.rs
+++ b/src/rustc/middle/kind.rs
@@ -144,12 +144,10 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
 
     let fty = ty::node_id_to_type(cx.tcx, id);
     match ty::ty_fn_proto(fty) {
-      ty::proto_vstore(ty::vstore_uniq) => b(check_for_uniq),
-      ty::proto_vstore(ty::vstore_box) => b(check_for_box),
-      ty::proto_bare => b(check_for_bare),
-      ty::proto_vstore(ty::vstore_slice(_)) => b(check_for_block),
-      ty::proto_vstore(ty::vstore_fixed(_)) =>
-        fail ~"fixed vstore not allowed here"
+      proto_uniq => b(check_for_uniq),
+      proto_box => b(check_for_box),
+      proto_bare => b(check_for_bare),
+      proto_block => b(check_for_block)
     }
 }
 
diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs
index cf9ee1bc190..d600f63246a 100644
--- a/src/rustc/middle/mem_categorization.rs
+++ b/src/rustc/middle/mem_categorization.rs
@@ -383,22 +383,18 @@ impl &mem_categorization_ctxt {
             let ty = ty::node_id_to_type(self.tcx, fn_node_id);
             let proto = ty::ty_fn_proto(ty);
             match proto {
-              ty::proto_vstore(ty::vstore_slice(_)) => {
+              ast::proto_block => {
                 let upcmt = self.cat_def(id, span, expr_ty, *inner);
                 @{id:id, span:span,
                   cat:cat_stack_upvar(upcmt), lp:upcmt.lp,
                   mutbl:upcmt.mutbl, ty:upcmt.ty}
               }
-              ty::proto_bare |
-              ty::proto_vstore(ty::vstore_uniq) |
-              ty::proto_vstore(ty::vstore_box) => {
+              ast::proto_bare | ast::proto_uniq | ast::proto_box => {
                 // FIXME #2152 allow mutation of moved upvars
                 @{id:id, span:span,
                   cat:cat_special(sk_heap_upvar), lp:none,
                   mutbl:m_imm, ty:expr_ty}
               }
-              ty::proto_vstore(ty::vstore_fixed(_)) =>
-                fail ~"fixed vstore not allowed here"
             }
           }
 
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 0c7d04d143e..9054b5a4611 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -2043,8 +2043,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> option<ty::t> {
       }
       ty::ty_trait(_, _) => {
         some(ty::mk_fn(tcx, {purity: ast::impure_fn,
-                             proto: ty::proto_vstore(ty::vstore_slice
-                                                     (ty::re_static)),
+                             proto: ast::proto_box,
                              bounds: @~[],
                              inputs: ~[],
                              output: ty::mk_nil(tcx),
@@ -3775,11 +3774,8 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
           }
           ast::expr_addr_of(_, x) => { return trans_addr_of(bcx, x, dest); }
           ast::expr_fn(proto, decl, body, cap_clause) => {
-            // XXX: This syntax should be reworked a bit (in the parser I
-            // guess?); @fn() { ... } won't work.
-            return closure::trans_expr_fn(bcx, ty::ast_proto_to_proto(proto),
-                                          decl, body, e.id, cap_clause, none,
-                                          dest);
+            return closure::trans_expr_fn(bcx, proto, decl, body, e.id,
+                                       cap_clause, none, dest);
           }
           ast::expr_fn_block(decl, body, cap_clause) => {
             match check ty::get(expr_ty(bcx, e)).struct {
diff --git a/src/rustc/middle/trans/closure.rs b/src/rustc/middle/trans/closure.rs
index 997991a5aa2..80fde9955d0 100644
--- a/src/rustc/middle/trans/closure.rs
+++ b/src/rustc/middle/trans/closure.rs
@@ -347,7 +347,7 @@ fn load_environment(fcx: fn_ctxt,
 }
 
 fn trans_expr_fn(bcx: block,
-                 proto: ty::fn_proto,
+                 proto: ast::proto,
                  decl: ast::fn_decl,
                  body: ast::blk,
                  id: ast::node_id,
@@ -364,8 +364,8 @@ fn trans_expr_fn(bcx: block,
     let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
 
     let trans_closure_env = fn@(ck: ty::closure_kind) -> result {
-        let cap_vars = capture::compute_capture_vars(ccx.tcx, id, proto,
-                                                     cap_clause);
+        let cap_vars = capture::compute_capture_vars(
+            ccx.tcx, id, proto, cap_clause);
         let ret_handle = match is_loop_body { some(x) => x, none => none };
         let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, ck, id,
                                                    ret_handle);
@@ -382,19 +382,14 @@ fn trans_expr_fn(bcx: block,
     };
 
     let {bcx: bcx, val: closure} = match proto {
-      ty::proto_vstore(ty::vstore_slice(_)) =>
-        trans_closure_env(ty::ck_block),
-      ty::proto_vstore(ty::vstore_box) =>
-        trans_closure_env(ty::ck_box),
-      ty::proto_vstore(ty::vstore_uniq) =>
-        trans_closure_env(ty::ck_uniq),
-      ty::proto_bare => {
+      ast::proto_block => trans_closure_env(ty::ck_block),
+      ast::proto_box => trans_closure_env(ty::ck_box),
+      ast::proto_uniq => trans_closure_env(ty::ck_uniq),
+      ast::proto_bare => {
         trans_closure(ccx, sub_path, decl, body, llfn, no_self, none,
                       id, |_fcx| { }, |_bcx| { });
         {bcx: bcx, val: C_null(T_opaque_box_ptr(ccx))}
       }
-      ty::proto_vstore(ty::vstore_fixed(_)) =>
-        fail ~"vstore_fixed unexpected"
     };
     fill_fn_pair(bcx, get_dest_addr(dest), llfn, closure);
 
@@ -421,15 +416,11 @@ fn make_fn_glue(
     };
 
     return match ty::get(t).struct {
-      ty::ty_fn({proto: ty::proto_bare, _}) |
-      ty::ty_fn({proto: ty::proto_vstore(ty::vstore_slice(_)), _}) =>
-        bcx,
-      ty::ty_fn({proto: ty::proto_vstore(ty::vstore_uniq), _}) =>
-        fn_env(ty::ck_uniq),
-      ty::ty_fn({proto: ty::proto_vstore(ty::vstore_box), _}) =>
-        fn_env(ty::ck_box),
-      _ =>
-        fail ~"make_fn_glue invoked on non-function type"
+      ty::ty_fn({proto: ast::proto_bare, _}) |
+      ty::ty_fn({proto: ast::proto_block, _}) => bcx,
+      ty::ty_fn({proto: ast::proto_uniq, _}) => fn_env(ty::ck_uniq),
+      ty::ty_fn({proto: ast::proto_box, _}) => fn_env(ty::ck_box),
+      _ => fail ~"make_fn_glue invoked on non-function type"
     };
 }
 
diff --git a/src/rustc/middle/trans/foreign.rs b/src/rustc/middle/trans/foreign.rs
index a81e665356f..3eac4a7e663 100644
--- a/src/rustc/middle/trans/foreign.rs
+++ b/src/rustc/middle/trans/foreign.rs
@@ -960,7 +960,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
         let frameaddress_val = Call(bcx, frameaddress, ~[C_i32(0i32)]);
         let fty = ty::mk_fn(bcx.tcx(), {
             purity: ast::impure_fn,
-            proto: ty::proto_vstore(ty::vstore_slice(ty::re_static)),
+            proto: ast::proto_block,
             bounds: @~[],
             inputs: ~[{
                 mode: ast::expl(ast::by_val),
diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs
index 7f8752c84d4..ae93021583b 100644
--- a/src/rustc/middle/trans/reflect.rs
+++ b/src/rustc/middle/trans/reflect.rs
@@ -185,12 +185,10 @@ impl reflector {
               ast::extern_fn => 3u
             };
             let protoval = match fty.proto {
-              ty::proto_bare => 0u,
-              ty::proto_vstore(ty::vstore_uniq) => 2u,
-              ty::proto_vstore(ty::vstore_box) => 3u,
-              ty::proto_vstore(ty::vstore_slice(_)) => 4u,
-              ty::proto_vstore(ty::vstore_fixed(_)) =>
-                fail ~"fixed unexpected"
+              ast::proto_bare => 0u,
+              ast::proto_uniq => 2u,
+              ast::proto_box => 3u,
+              ast::proto_block => 4u
             };
             let retval = match fty.ret_style {
               ast::noreturn => 0u,
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index 68bddb8d151..4246defbe0f 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -351,20 +351,14 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> ~[u8] {
       ty::ty_param(*) => {
         ccx.tcx.sess.bug(~"non-monomorphized type parameter");
       }
-      ty::ty_fn({proto: ty::proto_vstore(ty::vstore_box), _}) =>
-        ~[shape_box_fn],
-      ty::ty_fn({proto: ty::proto_vstore(ty::vstore_uniq), _}) =>
-        ~[shape_uniq_fn],
-      ty::ty_fn({proto: ty::proto_vstore(ty::vstore_slice(_)), _}) =>
-        ~[shape_stack_fn],
-      ty::ty_fn({proto: ty::proto_vstore(ty::vstore_fixed(_)), _}) =>
-        fail ~"fixed vstore is impossible",
-      ty::ty_fn({proto: ty::proto_bare, _}) =>
-        ~[shape_bare_fn],
-      ty::ty_opaque_closure_ptr(_) =>
-        ~[shape_opaque_closure_ptr],
-      ty::ty_var(_) | ty::ty_var_integral(_) | ty::ty_self =>
-        ccx.sess.bug(~"shape_of: unexpected type struct found")
+      ty::ty_fn({proto: ast::proto_box, _}) => ~[shape_box_fn],
+      ty::ty_fn({proto: ast::proto_uniq, _}) => ~[shape_uniq_fn],
+      ty::ty_fn({proto: ast::proto_block, _}) => ~[shape_stack_fn],
+      ty::ty_fn({proto: ast::proto_bare, _}) => ~[shape_bare_fn],
+      ty::ty_opaque_closure_ptr(_) => ~[shape_opaque_closure_ptr],
+      ty::ty_var(_) | ty::ty_var_integral(_) | ty::ty_self => {
+        ccx.sess.bug(~"shape_of: unexpected type struct found");
+      }
     }
 }
 
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index d630653ef27..c21ad7c992b 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -202,16 +202,13 @@ fn mark_for_expr(cx: ctx, e: @expr) {
       }
       expr_fn(*) | expr_fn_block(*) => {
         match ty::ty_fn_proto(ty::expr_ty(cx.ccx.tcx, e)) {
-          ty::proto_bare | ty::proto_vstore(ty::vstore_uniq) => {}
-          ty::proto_vstore(ty::vstore_box) |
-          ty::proto_vstore(ty::vstore_slice(_)) => {
+          proto_bare | proto_uniq => {}
+          proto_box | proto_block => {
             for vec::each(*freevars::get_freevars(cx.ccx.tcx, e.id)) |fv| {
                 let node_id = ast_util::def_id_of_def(fv.def).node;
                 node_type_needs(cx, use_repr, node_id);
             }
           }
-          ty::proto_vstore(ty::vstore_fixed(_)) =>
-            fail ~"vstore_fixed not allowed here"
         }
       }
       expr_assign(val, _) | expr_swap(val, _) | expr_assign_op(_, val, _) |
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index b74dad6cda9..90ea9b3a6b1 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -171,13 +171,9 @@ export terr_sorts, terr_vec, terr_str, terr_record_size, terr_tuple_size;
 export terr_regions_differ, terr_mutability, terr_purity_mismatch;
 export terr_proto_mismatch;
 export terr_ret_style_mismatch;
-export terr_fn;
 export purity_to_str;
 export param_tys_in_type;
 export eval_repeat_count;
-export fn_proto, proto_bare, proto_vstore;
-export ast_proto_to_proto;
-export is_blockish;
 
 // Data types
 
@@ -320,11 +316,6 @@ enum closure_kind {
     ck_uniq,
 }
 
-enum fn_proto {
-    proto_bare,             // supertype of all other protocols
-    proto_vstore(vstore)
-}
-
 /// Innards of a function type:
 ///
 /// - `purity` is the function's effect (pure, impure, unsafe).
@@ -334,7 +325,7 @@ enum fn_proto {
 /// - `output` is the return type.
 /// - `ret_style` indicates whether the function returns a value or fails.
 type fn_ty = {purity: ast::purity,
-              proto: fn_proto,
+              proto: ast::proto,
               bounds: @~[param_bound],
               inputs: ~[arg],
               output: t,
@@ -451,7 +442,7 @@ enum sty {
 }
 
 enum terr_vstore_kind {
-    terr_vec, terr_str, terr_fn
+    terr_vec, terr_str
 }
 
 // Data structures used in type unification
@@ -460,7 +451,7 @@ enum type_err {
     terr_ret_style_mismatch(ast::ret_style, ast::ret_style),
     terr_purity_mismatch(purity, purity),
     terr_mutability,
-    terr_proto_mismatch(ty::fn_proto, ty::fn_proto),
+    terr_proto_mismatch(ast::proto, ast::proto),
     terr_box_mutability,
     terr_ptr_mutability,
     terr_ref_mutability,
@@ -1317,7 +1308,7 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
       }
       ty_fn(ref fty) => {
         match fty.proto {
-          proto_bare | proto_vstore(vstore_slice(_)) => false,
+          proto_bare | proto_block => false,
           _ => true
         }
       }
@@ -1557,18 +1548,13 @@ pure fn kind_is_owned(k: kind) -> bool {
     *k & KIND_MASK_OWNED == KIND_MASK_OWNED
 }
 
-fn proto_kind(p: fn_proto) -> kind {
+fn proto_kind(p: proto) -> kind {
     match p {
-      proto_vstore(vstore_slice(_)) =>
-        kind_noncopyable() | kind_(KIND_MASK_DEFAULT_MODE),
-      proto_vstore(vstore_box) =>
-        kind_safe_for_default_mode() | kind_owned(),
-      proto_vstore(vstore_uniq) =>
-        kind_send_copy() | kind_owned(),
-      proto_vstore(vstore_fixed(_)) =>
-        fail ~"fixed vstore protos are not allowed",
-      proto_bare =>
-        kind_safe_for_default_mode_send() | kind_const() | kind_owned()
+      ast::proto_block => kind_noncopyable() | kind_(KIND_MASK_DEFAULT_MODE),
+      ast::proto_box => kind_safe_for_default_mode() | kind_owned(),
+      ast::proto_uniq => kind_send_copy() | kind_owned(),
+      ast::proto_bare => kind_safe_for_default_mode_send() | kind_const() |
+                           kind_owned()
     }
 }
 
@@ -2307,7 +2293,7 @@ fn ty_fn_args(fty: t) -> ~[arg] {
     }
 }
 
-fn ty_fn_proto(fty: t) -> fn_proto {
+fn ty_fn_proto(fty: t) -> ast::proto {
     match get(fty).struct {
       ty_fn(ref f) => f.proto,
       _ => fail ~"ty_fn_proto() called on non-fn type"
@@ -2590,11 +2576,7 @@ fn ty_sort_str(cx: ctxt, t: t) -> ~str {
 
 fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
     fn terr_vstore_kind_to_str(k: terr_vstore_kind) -> ~str {
-        match k {
-            terr_vec => ~"[]",
-            terr_str => ~"str",
-            terr_fn => ~"fn"
-        }
+        match k { terr_vec => ~"[]", terr_str => ~"str" }
     }
 
     match *err {
@@ -2615,8 +2597,7 @@ fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
       }
       terr_proto_mismatch(e, a) => {
         return fmt!{"closure protocol mismatch (%s vs %s)",
-                    util::ppaux::proto_ty_to_str(cx, e),
-                    util::ppaux::proto_ty_to_str(cx, a)};
+                 proto_to_str(e), proto_to_str(a)};
       }
       terr_mutability => return ~"values differ in mutability",
       terr_box_mutability => return ~"boxed values differ in mutability",
@@ -3273,26 +3254,6 @@ fn eval_repeat_count(tcx: ctxt, count_expr: @ast::expr, span: span) -> uint {
     }
 }
 
-fn ast_proto_to_proto(ast_proto: ast::proto) -> ty::fn_proto {
-    match ast_proto {
-        ast::proto_bare => ty::proto_bare,
-        ast::proto_uniq => ty::proto_vstore(ty::vstore_uniq),
-        ast::proto_box => ty::proto_vstore(ty::vstore_box),
-        ast::proto_block => ty::proto_vstore(ty::vstore_slice(ty::re_static))
-    }
-}
-
-pure fn is_blockish(proto: fn_proto) -> bool {
-    match proto {
-        proto_vstore(vstore_slice(_)) =>
-            true,
-        proto_vstore(vstore_box) | proto_vstore(vstore_uniq) | proto_bare =>
-            false,
-        proto_vstore(vstore_fixed(_)) =>
-            fail ~"fixed vstore not allowed here"
-    }
-}
-
 // Local Variables:
 // mode: rust
 // fill-column: 78;
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 88469c33516..35ef1d5406e 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -251,7 +251,7 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
     let tcx = ccx.tcx;
     let main_t = ty::node_id_to_type(tcx, main_id);
     match ty::get(main_t).struct {
-      ty::ty_fn({purity: ast::impure_fn, proto: ty::proto_bare, bounds,
+      ty::ty_fn({purity: ast::impure_fn, proto: ast::proto_bare, bounds,
                  inputs, output, ret_style: ast::return_val}) => {
         match tcx.items.find(main_id) {
          some(ast_map::node_item(it,_)) => {
diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs
index c6ede5bf817..124c5154a46 100644
--- a/src/rustc/middle/typeck/astconv.rs
+++ b/src/rustc/middle/typeck/astconv.rs
@@ -423,7 +423,7 @@ type expected_tys = option<{inputs: ~[ty::arg],
 
 fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
     self: AC, rscope: RS,
-    ast_proto: ast::proto,
+    proto: ast::proto,
     bounds: @~[ty::param_bound],
     decl: ast::fn_decl,
     expected_tys: expected_tys) -> ty::fn_ty {
@@ -450,8 +450,6 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
           _ => ast_ty_to_ty(self, rb, decl.output)
         };
 
-        let proto = ty::ast_proto_to_proto(ast_proto);
-
         {purity: decl.purity, proto: proto, bounds: bounds, inputs: input_tys,
          output: output_ty, ret_style: decl.cf}
     }
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 3bb2d0974ec..8dea6d6cfba 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -1116,14 +1116,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         }
     }
 
-    enum fn_or_ast_proto {
-        foap_fn_proto(ty::fn_proto),
-        foap_ast_proto(ast::proto)
-    }
-
     fn check_expr_fn(fcx: @fn_ctxt,
                      expr: @ast::expr,
-                     fn_or_ast_proto: fn_or_ast_proto,
+                     proto: ast::proto,
                      decl: ast::fn_decl,
                      body: ast::blk,
                      is_loop_body: bool,
@@ -1148,29 +1143,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
             }
         };
 
-        let ast_proto;
-        match fn_or_ast_proto {
-            foap_fn_proto(fn_proto) => {
-                // Generate a fake AST prototype. We'll fill in the type with
-                // the real one later.
-                // XXX: This is a hack.
-                ast_proto = ast::proto_box;
-            }
-            foap_ast_proto(existing_ast_proto) => {
-                ast_proto = existing_ast_proto;
-            }
-        }
-
         // construct the function type
-        let mut fn_ty = astconv::ty_of_fn_decl(fcx, fcx, ast_proto, @~[],
-                                               decl, expected_tys);
-
-        // Patch up the function declaration, if necessary.
-        match fn_or_ast_proto {
-            foap_fn_proto(fn_proto) => fn_ty.proto = fn_proto,
-            foap_ast_proto(_) => {}
-        }
-
+        let fn_ty = astconv::ty_of_fn_decl(fcx, fcx, proto, @~[],
+                                           decl, expected_tys);
         let fty = ty::mk_fn(tcx, fn_ty);
 
         debug!{"check_expr_fn_with_unifier %s fty=%s",
@@ -1510,17 +1485,15 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         bot = alt::check_alt(fcx, expr, discrim, arms);
       }
       ast::expr_fn(proto, decl, body, cap_clause) => {
-        check_expr_fn(fcx, expr, foap_ast_proto(proto), decl, body, false,
-                      expected);
+        check_expr_fn(fcx, expr, proto, decl, body, false, expected);
         capture::check_capture_clause(tcx, expr.id, cap_clause);
       }
       ast::expr_fn_block(decl, body, cap_clause) => {
          // Take the prototype from the expected type, but default to block:
           let proto = unpack_expected(fcx, expected, |sty|
               match sty { ty::ty_fn({proto, _}) => some(proto), _ => none }
-          ).get_default(ty::proto_vstore(ty::vstore_box));
-        check_expr_fn(fcx, expr, foap_fn_proto(proto), decl, body, false,
-                      expected);
+          ).get_default(ast::proto_box);
+        check_expr_fn(fcx, expr, proto, decl, body, false, expected);
         capture::check_capture_clause(tcx, expr.id, cap_clause);
       }
       ast::expr_loop_body(b) => {
@@ -1552,8 +1525,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         };
         match check b.node {
           ast::expr_fn_block(decl, body, cap_clause) => {
-            check_expr_fn(fcx, b, foap_fn_proto(proto), decl, body, true,
-                          some(inner_ty));
+            check_expr_fn(fcx, b, proto, decl, body, true, some(inner_ty));
             demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
             capture::check_capture_clause(tcx, b.id, cap_clause);
           }
@@ -1581,8 +1553,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         };
         match check b.node {
           ast::expr_fn_block(decl, body, cap_clause) => {
-            check_expr_fn(fcx, b, foap_fn_proto(proto), decl, body, true,
-                          some(inner_ty));
+            check_expr_fn(fcx, b, proto, decl, body, true, some(inner_ty));
             demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
             capture::check_capture_clause(tcx, b.id, cap_clause);
           }
@@ -2467,7 +2438,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
       ~"frame_address" => {
         let fty = ty::mk_fn(ccx.tcx, {
             purity: ast::impure_fn,
-            proto: ty::proto_vstore(ty::vstore_slice(ty::re_static)),
+            proto: ast::proto_block,
             bounds: @~[],
             inputs: ~[{
                 mode: ast::expl(ast::by_val),
@@ -2487,7 +2458,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
       }
     };
     let fty = ty::mk_fn(tcx, {purity: ast::impure_fn,
-                              proto: ty::proto_bare,
+                              proto: ast::proto_bare,
                               bounds: @~[],
                               inputs: inputs, output: output,
                               ret_style: ast::return_val});
diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs
index 274eab9242e..3091e28d556 100644
--- a/src/rustc/middle/typeck/check/method.rs
+++ b/src/rustc/middle/typeck/check/method.rs
@@ -334,8 +334,7 @@ class lookup {
     fn ty_from_did(did: ast::def_id) -> ty::t {
         match check ty::get(ty::lookup_item_type(self.tcx(), did).ty).struct {
           ty::ty_fn(fty) => {
-            ty::mk_fn(self.tcx(),
-                      {proto: ty::proto_vstore(ty::vstore_box) with fty})
+            ty::mk_fn(self.tcx(), {proto: ast::proto_box with fty})
           }
         }
         /*
@@ -417,8 +416,7 @@ class lookup {
 
         // a bit hokey, but the method unbound has a bare protocol, whereas
         // a.b has a protocol like fn@() (perhaps eventually fn&()):
-        let fty = ty::mk_fn(tcx, {proto: ty::proto_vstore(ty::vstore_box)
-                                  with m.fty});
+        let fty = ty::mk_fn(tcx, {proto: ast::proto_box with m.fty});
 
         self.candidates.push(
             {self_ty: self.self_ty,
diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs
index 0eaa435e32d..477ea6d0e34 100644
--- a/src/rustc/middle/typeck/collect.rs
+++ b/src/rustc/middle/typeck/collect.rs
@@ -126,8 +126,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
                 });
                 result_ty = some(ty::mk_fn(tcx,
                                            {purity: ast::pure_fn,
-                                            proto: ty::proto_vstore
-                                                (ty::vstore_box),
+                                            proto: ast::proto_box,
                                             bounds: @~[],
                                             inputs: args,
                                             output: enum_ty,
@@ -475,7 +474,7 @@ fn convert_struct(ccx: @crate_ctxt, rp: bool, struct_def: @ast::struct_def,
              tps: ty::ty_params_to_tys(tcx, tps)});
         let t_ctor = ty::mk_fn(
             tcx, {purity: ast::impure_fn,
-                  proto: ty::proto_vstore(ty::vstore_slice(ty::re_static)),
+                  proto: ast::proto_block,
                   bounds: @~[],
                   inputs: t_args,
                   output: t_res,
@@ -727,7 +726,7 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
     let output_ty = ast_ty_to_ty(ccx, rb, decl.output);
 
     let t_fn = ty::mk_fn(ccx.tcx, {purity: decl.purity,
-                                   proto: ty::proto_bare,
+                                   proto: ast::proto_bare,
                                    bounds: @~[],
                                    inputs: input_tys,
                                    output: output_ty,
diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs
index 13735e2f6d0..38913a5b605 100644
--- a/src/rustc/middle/typeck/infer.rs
+++ b/src/rustc/middle/typeck/infer.rs
@@ -172,7 +172,7 @@ import std::smallintmap::smallintmap;
 import std::map::hashmap;
 import middle::ty;
 import middle::ty::{tv_vid, tvi_vid, region_vid, vid,
-                    ty_int, ty_uint, get, terr_fn};
+                    ty_int, ty_uint, get};
 import syntax::{ast, ast_util};
 import syntax::ast::{ret_style, purity};
 import util::ppaux::{ty_to_str, mt_to_str};
@@ -1552,7 +1552,7 @@ trait combine {
     fn flds(a: ty::field, b: ty::field) -> cres<ty::field>;
     fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode>;
     fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg>;
-    fn protos(p1: ty::fn_proto, p2: ty::fn_proto) -> cres<ty::fn_proto>;
+    fn protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto>;
     fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style>;
     fn purities(f1: purity, f2: purity) -> cres<purity>;
     fn contraregions(a: ty::region, b: ty::region) -> cres<ty::region>;
@@ -1945,7 +1945,7 @@ impl sub: combine {
         }
     }
 
-    fn protos(a: ty::fn_proto, b: ty::fn_proto) -> cres<ty::fn_proto> {
+    fn protos(a: ast::proto, b: ast::proto) -> cres<ast::proto> {
         (&self.lub()).protos(a, b).compare(b, || {
             ty::terr_proto_mismatch(b, a)
         })
@@ -2103,20 +2103,15 @@ impl lub: combine {
         glb(self.infcx()).tys(a, b)
     }
 
-    fn protos(p1: ty::fn_proto, p2: ty::fn_proto) -> cres<ty::fn_proto> {
-        match (p1, p2) {
-            (ty::proto_bare, _) => ok(p2),
-            (_, ty::proto_bare) => ok(p1),
-            (ty::proto_vstore(v1), ty::proto_vstore(v2)) => {
-                self.infcx().try(|| {
-                    do self.vstores(terr_fn, v1, v2).chain |vs| {
-                        ok(ty::proto_vstore(vs))
-                    }
-                }).chain_err(|_err| {
-                    // XXX: Totally unsound, but fixed up later.
-                    ok(ty::proto_vstore(ty::vstore_slice(ty::re_static)))
-                })
-            }
+    fn protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto> {
+        if p1 == ast::proto_bare {
+            ok(p2)
+        } else if p2 == ast::proto_bare {
+            ok(p1)
+        } else if p1 == p2 {
+            ok(p1)
+        } else {
+            ok(ast::proto_block)
         }
     }
 
@@ -2305,21 +2300,15 @@ impl glb: combine {
         lub(self.infcx()).tys(a, b)
     }
 
-    fn protos(p1: ty::fn_proto, p2: ty::fn_proto) -> cres<ty::fn_proto> {
-        match (p1, p2) {
-            (ty::proto_vstore(ty::vstore_slice(_)), _) => ok(p2),
-            (_, ty::proto_vstore(ty::vstore_slice(_))) => ok(p1),
-            (ty::proto_vstore(v1), ty::proto_vstore(v2)) => {
-                self.infcx().try(|| {
-                    do self.vstores(terr_fn, v1, v2).chain |vs| {
-                        ok(ty::proto_vstore(vs))
-                    }
-                }).chain_err(|_err| {
-                    // XXX: Totally unsound, but fixed up later.
-                    ok(ty::proto_bare)
-                })
-            }
-            _ => ok(ty::proto_bare)
+    fn protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto> {
+        if p1 == ast::proto_block {
+            ok(p2)
+        } else if p2 == ast::proto_block {
+            ok(p1)
+        } else if p1 == p2 {
+            ok(p1)
+        } else {
+            ok(ast::proto_bare)
         }
     }
 
diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs
index c43a76d6a42..b64c7232137 100644
--- a/src/rustc/util/ppaux.rs
+++ b/src/rustc/util/ppaux.rs
@@ -188,13 +188,6 @@ fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str {
     }
 }
 
-fn proto_ty_to_str(cx: ctxt, proto: ty::fn_proto) -> ~str {
-    match proto {
-      ty::proto_bare => ~"",
-      ty::proto_vstore(vstore) => vstore_to_str(cx, vstore)
-    }
-}
-
 fn tys_to_str(cx: ctxt, ts: ~[t]) -> ~str {
     let mut rs = ~"";
     for ts.each |t| { rs += ty_to_str(cx, t); }
@@ -218,7 +211,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
         };
         modestr + ty_to_str(cx, ty)
     }
-    fn fn_to_str(cx: ctxt, purity: ast::purity, proto: ty::fn_proto,
+    fn fn_to_str(cx: ctxt, purity: ast::purity, proto: ast::proto,
                  ident: option<ast::ident>,
                  inputs: ~[arg], output: t, cf: ast::ret_style) -> ~str {
         let mut s;
@@ -227,8 +220,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
           ast::impure_fn => ~"",
           _ => purity_to_str(purity) + ~" "
         };
-
-        s += proto_ty_to_str(cx, proto);
+        s += proto_to_str(proto);
         match ident {
           some(i) => { s += ~" "; s += *i; }
           _ => { }