about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-12 22:21:56 -0700
committerbors <bors@rust-lang.org>2014-04-12 22:21:56 -0700
commit96aeb7e3c35ee0d0cf5b9ab8db5ef69e4cfb264e (patch)
tree37b06241edd266e498e4fa8e715bcc2e7784d387 /src
parente4178db07c5747ea412118c8e64f3fbefad4338e (diff)
parent9d570ad8c16970e1b2f629d224716f2d7a8b7820 (diff)
downloadrust-96aeb7e3c35ee0d0cf5b9ab8db5ef69e4cfb264e.tar.gz
rust-96aeb7e3c35ee0d0cf5b9ab8db5ef69e4cfb264e.zip
auto merge of #13461 : eddyb/rust/cleanup-at-fn, r=luqmana
Diffstat (limited to 'src')
-rw-r--r--src/librustc/front/feature_gate.rs3
-rw-r--r--src/librustc/metadata/tydecode.rs15
-rw-r--r--src/librustc/metadata/tyencode.rs11
-rw-r--r--src/librustc/middle/astencode.rs13
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs11
-rw-r--r--src/librustc/middle/borrowck/mod.rs2
-rw-r--r--src/librustc/middle/kind.rs26
-rw-r--r--src/librustc/middle/lint.rs6
-rw-r--r--src/librustc/middle/mem_categorization.rs33
-rw-r--r--src/librustc/middle/moves.rs46
-rw-r--r--src/librustc/middle/resolve.rs2
-rw-r--r--src/librustc/middle/resolve_lifetime.rs4
-rw-r--r--src/librustc/middle/trans/base.rs2
-rw-r--r--src/librustc/middle/trans/closure.rs60
-rw-r--r--src/librustc/middle/trans/consts.rs10
-rw-r--r--src/librustc/middle/trans/debuginfo.rs8
-rw-r--r--src/librustc/middle/trans/expr.rs28
-rw-r--r--src/librustc/middle/trans/glue.rs2
-rw-r--r--src/librustc/middle/trans/reflect.rs13
-rw-r--r--src/librustc/middle/ty.rs100
-rw-r--r--src/librustc/middle/ty_fold.rs3
-rw-r--r--src/librustc/middle/typeck/astconv.rs84
-rw-r--r--src/librustc/middle/typeck/check/mod.rs66
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs24
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs13
-rw-r--r--src/librustc/middle/typeck/infer/coercion.rs34
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs38
-rw-r--r--src/librustc/middle/typeck/variance.rs6
-rw-r--r--src/librustc/util/ppaux.rs62
-rw-r--r--src/librustdoc/clean.rs10
-rw-r--r--src/librustdoc/html/format.rs21
-rw-r--r--src/libsyntax/ast.rs22
-rw-r--r--src/libsyntax/fold.rs13
-rw-r--r--src/libsyntax/parse/parser.rs32
-rw-r--r--src/libsyntax/print/pprust.rs48
-rw-r--r--src/libsyntax/visit.rs15
36 files changed, 334 insertions, 552 deletions
diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs
index 5c0b9c89565..dd604af40ec 100644
--- a/src/librustc/front/feature_gate.rs
+++ b/src/librustc/front/feature_gate.rs
@@ -260,8 +260,7 @@ impl<'a> Visitor<()> for Context<'a> {
 
     fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
         match t.node {
-            ast::TyClosure(closure) if closure.onceness == ast::Once &&
-                    closure.sigil != ast::OwnedSigil => {
+            ast::TyClosure(closure, _) if closure.onceness == ast::Once => {
                 self.gate_feature("once_fns", t.span,
                                   "once functions are \
                                    experimental and likely to be removed");
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index f29b181125e..5df5b718f3e 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -137,15 +137,6 @@ pub fn parse_substs_data(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx:
     parse_substs(&mut st, conv)
 }
 
-fn parse_sigil(st: &mut PState) -> ast::Sigil {
-    match next(st) {
-        '@' => ast::ManagedSigil,
-        '~' => ast::OwnedSigil,
-        '&' => ast::BorrowedSigil,
-        c => st.tcx.sess.bug(format!("parse_sigil(): bad input '{}'", c))
-    }
-}
-
 fn parse_vstore<M>(st: &mut PState, conv: conv_did,
                    parse_mut: |&mut PState| -> M) -> ty::Vstore<M> {
     assert_eq!(next(st), '/');
@@ -476,17 +467,15 @@ fn parse_onceness(c: char) -> ast::Onceness {
 }
 
 fn parse_closure_ty(st: &mut PState, conv: conv_did) -> ty::ClosureTy {
-    let sigil = parse_sigil(st);
     let fn_style = parse_fn_style(next(st));
     let onceness = parse_onceness(next(st));
-    let region = parse_region(st, |x,y| conv(x,y));
+    let store = parse_trait_store(st, |x,y| conv(x,y));
     let bounds = parse_bounds(st, |x,y| conv(x,y));
     let sig = parse_sig(st, |x,y| conv(x,y));
     ty::ClosureTy {
         fn_style: fn_style,
-        sigil: sigil,
         onceness: onceness,
-        region: region,
+        store: store,
         bounds: bounds.builtin_bounds,
         sig: sig
     }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index d8c5197df27..53fe1c19d8f 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -327,14 +327,6 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
     }
 }
 
-fn enc_sigil(w: &mut MemWriter, sigil: Sigil) {
-    match sigil {
-        ManagedSigil => mywrite!(w, "@"),
-        OwnedSigil => mywrite!(w, "~"),
-        BorrowedSigil => mywrite!(w, "&"),
-    }
-}
-
 fn enc_fn_style(w: &mut MemWriter, p: FnStyle) {
     match p {
         NormalFn => mywrite!(w, "n"),
@@ -363,10 +355,9 @@ pub fn enc_bare_fn_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::BareFnTy) {
 }
 
 fn enc_closure_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::ClosureTy) {
-    enc_sigil(w, ft.sigil);
     enc_fn_style(w, ft.fn_style);
     enc_onceness(w, ft.onceness);
-    enc_region(w, cx, ft.region);
+    enc_trait_store(w, cx, ft.store);
     let bounds = ty::ParamBounds {builtin_bounds: ft.bounds,
                                   trait_bounds: Vec::new()};
     enc_bounds(w, cx, &bounds);
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index ebddc0525ea..858e873f7ed 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -897,10 +897,9 @@ impl<'a> ebml_writer_helpers for Encoder<'a> {
     fn emit_auto_adjustment(&mut self, ecx: &e::EncodeContext, adj: &ty::AutoAdjustment) {
         self.emit_enum("AutoAdjustment", |this| {
             match *adj {
-                ty::AutoAddEnv(region, sigil) => {
-                    this.emit_enum_variant("AutoAddEnv", 0, 2, |this| {
-                        this.emit_enum_variant_arg(0, |this| region.encode(this));
-                        this.emit_enum_variant_arg(1, |this| sigil.encode(this))
+                ty::AutoAddEnv(store) => {
+                    this.emit_enum_variant("AutoAddEnv", 0, 1, |this| {
+                        this.emit_enum_variant_arg(0, |this| store.encode(this))
                     })
                 }
 
@@ -1270,12 +1269,10 @@ impl<'a> ebml_decoder_decoder_helpers for reader::Decoder<'a> {
             this.read_enum_variant(variants, |this, i| {
                 Ok(match i {
                     0 => {
-                        let region: ty::Region =
+                        let store: ty::TraitStore =
                             this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
-                        let sigil: ast::Sigil =
-                            this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
 
-                        ty:: AutoAddEnv(region.tr(xcx), sigil)
+                        ty:: AutoAddEnv(store.tr(xcx))
                     }
                     1 => {
                         let auto_deref_ref: ty::AutoDerefRef =
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index a6409131bed..f0a6c5f16f7 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -451,17 +451,8 @@ impl<'a> GatherLoanCtxt<'a> {
                                              r,
                                              AutoRef)
                     }
-                    ty::AutoBorrowFn(r) => {
-                        let cmt_deref = mc.cat_deref_fn_or_obj(expr, cmt, 0);
-                        self.guarantee_valid(expr.id,
-                                             expr.span,
-                                             cmt_deref,
-                                             ast::MutImmutable,
-                                             r,
-                                             AutoRef)
-                    }
                     ty::AutoBorrowObj(r, m) => {
-                        let cmt_deref = mc.cat_deref_fn_or_obj(expr, cmt, 0);
+                        let cmt_deref = mc.cat_deref_obj(expr, cmt);
                         self.guarantee_valid(expr.id,
                                              expr.span,
                                              cmt_deref,
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 83c45dc830f..21e68e2724f 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -620,7 +620,7 @@ impl<'a> BorrowckCtxt<'a> {
         fn move_suggestion(tcx: &ty::ctxt, ty: ty::t, default_msg: &'static str)
                           -> &'static str {
             match ty::get(ty).sty {
-                ty::ty_closure(ref cty) if cty.sigil == ast::BorrowedSigil =>
+                ty::ty_closure(~ty::ClosureTy { store: ty::RegionTraitStore(..), .. }) =>
                     "a non-copyable stack closure (capture it in a new closure, \
                      e.g. `|x| f(x)`, to override)",
                 _ if ty::type_moves_by_default(tcx, ty) =>
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 09f396e932f..a152e06eb06 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -197,27 +197,13 @@ fn with_appropriate_checker(cx: &Context,
     let fty = ty::node_id_to_type(cx.tcx, id);
     match ty::get(fty).sty {
         ty::ty_closure(~ty::ClosureTy {
-            sigil: OwnedSigil,
-            bounds: bounds,
-            ..
-        }) => {
-            b(|cx, fv| check_for_uniq(cx, fv, bounds))
-        }
-        ty::ty_closure(~ty::ClosureTy {
-            sigil: ManagedSigil,
-            ..
-        }) => {
-            // can't happen
-            fail!("internal error: saw closure with managed sigil (@fn)");
-        }
+            store: ty::UniqTraitStore, bounds, ..
+        }) => b(|cx, fv| check_for_uniq(cx, fv, bounds)),
+
         ty::ty_closure(~ty::ClosureTy {
-            sigil: BorrowedSigil,
-            bounds: bounds,
-            region: region,
-            ..
-        }) => {
-            b(|cx, fv| check_for_block(cx, fv, bounds, region))
-        }
+            store: ty::RegionTraitStore(region, _), bounds, ..
+        }) => b(|cx, fv| check_for_block(cx, fv, bounds, region)),
+
         ty::ty_bare_fn(_) => {
             b(check_for_bare)
         }
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 16af63c4e16..e376f85ff6d 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -919,10 +919,8 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
                 }
                 ty::ty_uniq(_) | ty::ty_str(ty::VstoreUniq) |
                 ty::ty_vec(_, ty::VstoreUniq) |
-                ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) => {
-                    n_uniq += 1;
-                }
-                ty::ty_closure(ref c) if c.sigil == ast::OwnedSigil => {
+                ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
+                ty::ty_closure(~ty::ClosureTy { store: ty::UniqTraitStore, .. }) => {
                     n_uniq += 1;
                 }
 
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index a5da9e7f9d0..7f157e321ba 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -76,7 +76,7 @@ use syntax::parse::token;
 pub enum categorization {
     cat_rvalue(ty::Region),            // temporary val, argument is its scope
     cat_static_item,
-    cat_copied_upvar(CopiedUpvar),     // upvar copied into @fn or ~fn env
+    cat_copied_upvar(CopiedUpvar),     // upvar copied into proc env
     cat_upvar(ty::UpvarId, ty::UpvarBorrow), // by ref upvar from stack closure
     cat_local(ast::NodeId),            // local variable
     cat_arg(ast::NodeId),              // formal argument
@@ -172,7 +172,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
         ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
         ty::ty_vec(_, ty::VstoreUniq) |
         ty::ty_str(ty::VstoreUniq) |
-        ty::ty_closure(~ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
+        ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
             Some(deref_ptr(OwnedPtr))
         }
 
@@ -187,8 +187,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
         }
 
         ty::ty_str(ty::VstoreSlice(r, ())) |
-        ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil,
-                                      region: r, ..}) => {
+        ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(r, _), ..}) => {
             Some(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
         }
 
@@ -540,15 +539,14 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
                       // Decide whether to use implicit reference or by copy/move
                       // capture for the upvar. This, combined with the onceness,
                       // determines whether the closure can move out of it.
-                      let var_is_refd = match (closure_ty.sigil, closure_ty.onceness) {
+                      let var_is_refd = match (closure_ty.store, closure_ty.onceness) {
                           // Many-shot stack closures can never move out.
-                          (ast::BorrowedSigil, ast::Many) => true,
+                          (ty::RegionTraitStore(..), ast::Many) => true,
                           // 1-shot stack closures can move out.
-                          (ast::BorrowedSigil, ast::Once) => false,
+                          (ty::RegionTraitStore(..), ast::Once) => false,
                           // Heap closures always capture by copy/move, and can
                           // move out if they are once.
-                          (ast::OwnedSigil, _) |
-                          (ast::ManagedSigil, _) => false,
+                          (ty::UniqTraitStore, _) => false,
 
                       };
                       if var_is_refd {
@@ -688,19 +686,8 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
         }
     }
 
-    pub fn cat_deref_fn_or_obj<N:ast_node>(&mut self,
-                                           node: &N,
-                                           base_cmt: cmt,
-                                           deref_cnt: uint)
-                                           -> cmt {
-        // Bit of a hack: the "dereference" of a function pointer like
-        // `@fn()` is a mere logical concept. We interpret it as
-        // dereferencing the environment pointer; of course, we don't
-        // know what type lies at the other end, so we just call it
-        // `()` (the empty tuple).
-
-        let opaque_ty = ty::mk_tup(self.tcx(), Vec::new());
-        self.cat_deref_common(node, base_cmt, deref_cnt, opaque_ty)
+    pub fn cat_deref_obj<N:ast_node>(&mut self, node: &N, base_cmt: cmt) -> cmt {
+        self.cat_deref_common(node, base_cmt, 0, ty::mk_nil())
     }
 
     fn cat_deref<N:ast_node>(&mut self,
@@ -1105,7 +1092,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
               ~"static item"
           }
           cat_copied_upvar(_) => {
-              ~"captured outer variable in a heap closure"
+              ~"captured outer variable in a proc"
           }
           cat_rvalue(..) => {
               ~"non-lvalue"
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index dbc28f9fdd5..2029df38b10 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -650,30 +650,30 @@ impl<'a> VisitContext<'a> {
         let _indenter = indenter();
 
         let fn_ty = ty::node_id_to_type(self.tcx, fn_expr_id);
-        let sigil = ty::ty_closure_sigil(fn_ty);
         let freevars = freevars::get_freevars(self.tcx, fn_expr_id);
-        let v = if sigil == BorrowedSigil {
-            // || captures everything by ref
-            freevars.iter()
-                    .map(|fvar| CaptureVar {def: fvar.def, span: fvar.span, mode: CapRef})
-                    .collect()
-        } else {
-            // @fn() and ~fn() capture by copy or by move depending on type
-            freevars.iter()
-                    .map(|fvar| {
-                let fvar_def_id = ast_util::def_id_of_def(fvar.def).node;
-                let fvar_ty = ty::node_id_to_type(self.tcx, fvar_def_id);
-                debug!("fvar_def_id={:?} fvar_ty={}",
-                       fvar_def_id, ppaux::ty_to_str(self.tcx, fvar_ty));
-                let mode = if ty::type_moves_by_default(self.tcx, fvar_ty) {
-                    CapMove
-                } else {
-                    CapCopy
-                };
-                CaptureVar {def: fvar.def, span: fvar.span, mode:mode}
-
+        Rc::new(match ty::ty_closure_store(fn_ty) {
+            ty::RegionTraitStore(..) => {
+                // || captures everything by ref
+                freevars.iter()
+                        .map(|fvar| CaptureVar {def: fvar.def, span: fvar.span, mode: CapRef})
+                        .collect()
+            }
+            ty::UniqTraitStore => {
+                // proc captures by copy or by move depending on type
+                freevars.iter()
+                        .map(|fvar| {
+                    let fvar_def_id = ast_util::def_id_of_def(fvar.def).node;
+                    let fvar_ty = ty::node_id_to_type(self.tcx, fvar_def_id);
+                    debug!("fvar_def_id={:?} fvar_ty={}",
+                        fvar_def_id, ppaux::ty_to_str(self.tcx, fvar_ty));
+                    let mode = if ty::type_moves_by_default(self.tcx, fvar_ty) {
+                        CapMove
+                    } else {
+                        CapCopy
+                    };
+                    CaptureVar {def: fvar.def, span: fvar.span, mode:mode}
                 }).collect()
-        };
-        Rc::new(v)
+            }
+        })
     }
 }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 92acb81bbcb..e5b13adb4d0 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -4274,7 +4274,7 @@ impl<'a> Resolver<'a> {
                 });
             }
 
-            TyClosure(c) => {
+            TyClosure(c, _) | TyProc(c) => {
                 c.bounds.as_ref().map(|bounds| {
                     for bound in bounds.iter() {
                         self.resolve_type_parameter_bound(ty.id, bound);
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 8f4c8c84b68..130c93ac51e 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -112,7 +112,9 @@ impl<'a, 'b> Visitor<Scope<'a>> for LifetimeContext<'b> {
 
     fn visit_ty(&mut self, ty: &ast::Ty, scope: Scope<'a>) {
         match ty.node {
-            ast::TyClosure(c) => push_fn_scope(self, ty, scope, &c.lifetimes),
+            ast::TyClosure(c, _) | ast::TyProc(c) => {
+                push_fn_scope(self, ty, scope, &c.lifetimes);
+            }
             ast::TyBareFn(c) => push_fn_scope(self, ty, scope, &c.lifetimes),
             _ => visit::walk_ty(self, ty, scope),
         }
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 3007b643e0a..60d6e6850f7 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -260,7 +260,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
             // noalias because the actual object pointer is nested.
             ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
             ty::ty_vec(_, ty::VstoreUniq) | ty::ty_str(ty::VstoreUniq) |
-            ty::ty_closure(~ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
+            ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
                 unsafe {
                     llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
                 }
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index 8fbaa238754..bc80f88f623 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -38,17 +38,14 @@ use syntax::ast_util;
 // roughly as follows:
 //
 // struct rust_opaque_box {         // see rust_internal.h
-//   unsigned ref_count;            // only used for @fn()
-//   type_desc *tydesc;             // describes closure_data struct
-//   rust_opaque_box *prev;         // (used internally by memory alloc)
-//   rust_opaque_box *next;         // (used internally by memory alloc)
+//   unsigned ref_count;            // obsolete (part of @T's header)
+//   fn(void*) *drop_glue;          // destructor (for proc)
+//   rust_opaque_box *prev;         // obsolete (part of @T's header)
+//   rust_opaque_box *next;         // obsolete (part of @T's header)
 //   struct closure_data {
-//       type_desc *bound_tdescs[]; // bound descriptors
-//       struct {
-//         upvar1_t upvar1;
-//         ...
-//         upvarN_t upvarN;
-//       } bound_data;
+//       upvar1_t upvar1;
+//       ...
+//       upvarN_t upvarN;
 //    }
 // };
 //
@@ -158,24 +155,21 @@ fn tuplify_box_ty(tcx: &ty::ctxt, t: ty::t) -> ty::t {
 }
 
 fn allocate_cbox<'a>(bcx: &'a Block<'a>,
-                     sigil: ast::Sigil,
+                     store: ty::TraitStore,
                      cdata_ty: ty::t)
                      -> Result<'a> {
     let _icx = push_ctxt("closure::allocate_cbox");
     let tcx = bcx.tcx();
 
     // Allocate and initialize the box:
-    match sigil {
-        ast::ManagedSigil => {
-            tcx.sess.bug("trying to trans allocation of @fn")
-        }
-        ast::OwnedSigil => {
+    match store {
+        ty::UniqTraitStore => {
             let ty = type_of(bcx.ccx(), cdata_ty);
             let size = llsize_of(bcx.ccx(), ty);
             // we treat proc as @ here, which isn't ideal
             malloc_raw_dyn_managed(bcx, cdata_ty, ClosureExchangeMallocFnLangItem, size)
         }
-        ast::BorrowedSigil => {
+        ty::RegionTraitStore(..) => {
             let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
             let llbox = alloc_ty(bcx, cbox_ty, "__closure");
             rslt(bcx, llbox)
@@ -196,7 +190,7 @@ pub struct ClosureResult<'a> {
 pub fn store_environment<'a>(
                          bcx: &'a Block<'a>,
                          bound_values: Vec<EnvValue> ,
-                         sigil: ast::Sigil)
+                         store: ty::TraitStore)
                          -> ClosureResult<'a> {
     let _icx = push_ctxt("closure::store_environment");
     let ccx = bcx.ccx();
@@ -220,7 +214,7 @@ pub fn store_environment<'a>(
     }
 
     // allocate closure in the heap
-    let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, sigil, cdata_ty);
+    let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, store, cdata_ty);
 
     let llbox = PointerCast(bcx, llbox, llboxptr_ty);
     debug!("tuplify_box_ty = {}", ty_to_str(tcx, cbox_ty));
@@ -254,7 +248,7 @@ pub fn store_environment<'a>(
 // collects the upvars and packages them up for store_environment.
 fn build_closure<'a>(bcx0: &'a Block<'a>,
                      cap_vars: &[moves::CaptureVar],
-                     sigil: ast::Sigil)
+                     store: ty::TraitStore)
                      -> ClosureResult<'a> {
     let _icx = push_ctxt("closure::build_closure");
 
@@ -268,7 +262,11 @@ fn build_closure<'a>(bcx0: &'a Block<'a>,
         let datum = expr::trans_local_var(bcx, cap_var.def);
         match cap_var.mode {
             moves::CapRef => {
-                assert_eq!(sigil, ast::BorrowedSigil);
+                let is_region_closure = match store {
+                    ty::RegionTraitStore(..) => true,
+                    ty::UniqTraitStore => false
+                };
+                assert!(is_region_closure);
                 env_vals.push(EnvValue {action: EnvRef,
                                         datum: datum});
             }
@@ -283,7 +281,7 @@ fn build_closure<'a>(bcx0: &'a Block<'a>,
         }
     }
 
-    return store_environment(bcx, env_vals, sigil);
+    store_environment(bcx, env_vals, store)
 }
 
 // Given an enclosing block context, a new function context, a closure type,
@@ -291,7 +289,7 @@ fn build_closure<'a>(bcx0: &'a Block<'a>,
 // with the upvars and type descriptors.
 fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
                         cap_vars: &[moves::CaptureVar],
-                        sigil: ast::Sigil) -> &'a Block<'a> {
+                        store: ty::TraitStore) -> &'a Block<'a> {
     let _icx = push_ctxt("closure::load_environment");
 
     // Don't bother to create the block if there's nothing to load
@@ -316,9 +314,9 @@ fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
     let mut i = 0u;
     for cap_var in cap_vars.iter() {
         let mut upvarptr = GEPi(bcx, llcdata, [0u, i]);
-        match sigil {
-            ast::BorrowedSigil => { upvarptr = Load(bcx, upvarptr); }
-            ast::ManagedSigil | ast::OwnedSigil => {}
+        match store {
+            ty::RegionTraitStore(..) => { upvarptr = Load(bcx, upvarptr); }
+            ty::UniqTraitStore => {}
         }
         let def_id = ast_util::def_id_of_def(cap_var.def);
 
@@ -331,7 +329,7 @@ fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
                 cdata_ty,
                 env_pointer_alloca,
                 i,
-                sigil,
+                store,
                 cap_var.span);
         }
 
@@ -349,7 +347,7 @@ fn fill_fn_pair(bcx: &Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef)
 
 pub fn trans_expr_fn<'a>(
                      bcx: &'a Block<'a>,
-                     sigil: ast::Sigil,
+                     store: ty::TraitStore,
                      decl: &ast::FnDecl,
                      body: &ast::Block,
                      id: ast::NodeId,
@@ -359,7 +357,7 @@ pub fn trans_expr_fn<'a>(
      *
      * Translates the body of a closure expression.
      *
-     * - `sigil`
+     * - `store`
      * - `decl`
      * - `body`
      * - `id`: The id of the closure expression.
@@ -399,11 +397,11 @@ pub fn trans_expr_fn<'a>(
 
     let cap_vars = ccx.maps.capture_map.borrow().get_copy(&id);
     let ClosureResult {llbox, cdata_ty, bcx} =
-        build_closure(bcx, cap_vars.as_slice(), sigil);
+        build_closure(bcx, cap_vars.as_slice(), store);
     trans_closure(ccx, decl, body, llfn,
                   bcx.fcx.param_substs, id,
                   [], ty::ty_fn_ret(fty),
-                  |bcx| load_environment(bcx, cdata_ty, cap_vars.as_slice(), sigil));
+                  |bcx| load_environment(bcx, cdata_ty, cap_vars.as_slice(), store));
     fill_fn_pair(bcx, dest_addr, llfn, llbox);
 
     bcx
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 66de46aa31d..e0a54234fca 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -191,7 +191,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
         None => { }
         Some(adj) => {
             match *adj {
-                ty::AutoAddEnv(ty::ReStatic, ast::BorrowedSigil) => {
+                ty::AutoAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
                     let def = ty::resolve_expr(cx.tcx(), e);
                     let wrapper = closure::get_wrapper_for_bare_fn(cx,
                                                                    ety_adjusted,
@@ -200,13 +200,11 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
                                                                    is_local);
                     llconst = C_struct(cx, [wrapper, C_null(Type::i8p(cx))], false)
                 }
-                ty::AutoAddEnv(ref r, ref s) => {
+                ty::AutoAddEnv(store) => {
                     cx.sess()
                       .span_bug(e.span,
-                                format!("unexpected static function: region \
-                                         {:?} sigil {:?}",
-                                        *r,
-                                        *s))
+                                format!("unexpected static function: {:?}",
+                                        store))
                 }
                 ty::AutoObject(..) => {
                     cx.sess()
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 965276619e9..ae58e153258 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -394,7 +394,7 @@ pub fn create_captured_var_metadata(bcx: &Block,
                                     env_data_type: ty::t,
                                     env_pointer: ValueRef,
                                     env_index: uint,
-                                    closure_sigil: ast::Sigil,
+                                    closure_store: ty::TraitStore,
                                     span: Span) {
     if fn_should_be_ignored(bcx.fcx) {
         return;
@@ -443,11 +443,11 @@ pub fn create_captured_var_metadata(bcx: &Block,
          llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref())]
     };
 
-    let address_op_count = match closure_sigil {
-        ast::BorrowedSigil => {
+    let address_op_count = match closure_store {
+        ty::RegionTraitStore(..) => {
             address_operations.len()
         }
-        ast::ManagedSigil | ast::OwnedSigil => {
+        ty::UniqTraitStore => {
             address_operations.len() - 1
         }
     };
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 4515b5d086e..e19408520f6 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -62,7 +62,7 @@ use middle::trans::type_of;
 use middle::trans::write_guard;
 use middle::ty::struct_fields;
 use middle::ty::{AutoBorrowObj, AutoDerefRef, AutoAddEnv, AutoObject, AutoUnsafe};
-use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn};
+use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef};
 use middle::ty;
 use middle::typeck::MethodCall;
 use util::common::indenter;
@@ -200,14 +200,6 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
                 Some(AutoBorrowVecRef(..)) => {
                     unpack_datum!(bcx, auto_slice_and_ref(bcx, expr, datum))
                 }
-                Some(AutoBorrowFn(..)) => {
-                    let adjusted_ty = ty::adjust_ty(bcx.tcx(), expr.span, expr.id, datum.ty,
-                                                    Some(adjustment), |method_call| {
-                        bcx.ccx().maps.method_map.borrow()
-                           .find(&method_call).map(|method| method.ty)
-                    });
-                    unpack_datum!(bcx, auto_borrow_fn(bcx, adjusted_ty, datum))
-                }
                 Some(AutoBorrowObj(..)) => {
                     unpack_datum!(bcx, auto_borrow_obj(bcx, expr, datum))
                 }
@@ -225,20 +217,6 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
     debug!("after adjustments, datum={}", datum.to_str(bcx.ccx()));
     return DatumBlock {bcx: bcx, datum: datum};
 
-    fn auto_borrow_fn<'a>(
-                      bcx: &'a Block<'a>,
-                      adjusted_ty: ty::t,
-                      datum: Datum<Expr>)
-                      -> DatumBlock<'a, Expr> {
-        // Currently, all closure types are represented precisely the
-        // same, so no runtime adjustment is required, but we still
-        // must patchup the type.
-        DatumBlock {bcx: bcx,
-                    datum: Datum {val: datum.val,
-                                  ty: adjusted_ty,
-                                  kind: datum.kind}}
-    }
-
     fn auto_slice<'a>(
                   bcx: &'a Block<'a>,
                   expr: &ast::Expr,
@@ -731,10 +709,10 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
         ast::ExprFnBlock(decl, body) |
         ast::ExprProc(decl, body) => {
             let expr_ty = expr_ty(bcx, expr);
-            let sigil = ty::ty_closure_sigil(expr_ty);
+            let store = ty::ty_closure_store(expr_ty);
             debug!("translating block function {} with type {}",
                    expr_to_str(expr), expr_ty.repr(tcx));
-            closure::trans_expr_fn(bcx, sigil, decl, body, expr.id, dest)
+            closure::trans_expr_fn(bcx, store, decl, body, expr.id, dest)
         }
         ast::ExprCall(f, ref args) => {
             callee::trans_call(bcx, expr, f, callee::ArgExprs(args.as_slice()), dest)
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index f4b6ed235e8..98e135c27c4 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -323,7 +323,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                 bcx
             })
         }
-        ty::ty_closure(ref f) if f.sigil == ast::OwnedSigil => {
+        ty::ty_closure(ref f) if f.store == ty::UniqTraitStore => {
             let box_cell_v = GEPi(bcx, v0, [0u, abi::fn_field_box]);
             let env = Load(bcx, box_cell_v);
             let env_ptr_ty = Type::at_box(bcx.ccx(), Type::i8(bcx.ccx())).ptr_to();
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index c4b9c7f97ad..3fe494ad41b 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -218,7 +218,10 @@ impl<'a> Reflector<'a> {
           // FIXME (#4809): visitor should break out bare fns from other fns
           ty::ty_closure(ref fty) => {
             let pureval = ast_fn_style_constant(fty.fn_style);
-            let sigilval = ast_sigil_constant(fty.sigil);
+            let sigilval = match fty.store {
+                ty::UniqTraitStore => 2u,
+                ty::RegionTraitStore(..) => 4u,
+            };
             let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
             let extra = vec!(self.c_uint(pureval),
                           self.c_uint(sigilval),
@@ -397,14 +400,6 @@ pub fn emit_calls_to_trait_visit_ty<'a>(
     return final;
 }
 
-pub fn ast_sigil_constant(sigil: ast::Sigil) -> uint {
-    match sigil {
-        ast::OwnedSigil => 2u,
-        ast::ManagedSigil => 3u,
-        ast::BorrowedSigil => 4u,
-    }
-}
-
 pub fn ast_fn_style_constant(fn_style: ast::FnStyle) -> uint {
     match fn_style {
         ast::UnsafeFn => 1u,
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 0cb0d716ddc..af53c31ad4e 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -214,7 +214,7 @@ pub enum Variance {
 }
 
 pub enum AutoAdjustment {
-    AutoAddEnv(ty::Region, ast::Sigil),
+    AutoAddEnv(ty::TraitStore),
     AutoDerefRef(AutoDerefRef),
     AutoObject(ty::TraitStore,
                ty::BuiltinBounds,
@@ -239,9 +239,6 @@ pub enum AutoRef {
     /// Convert from ~[]/&[] to &&[] (or str)
     AutoBorrowVecRef(Region, ast::Mutability),
 
-    /// Convert from @fn()/~fn()/|| to ||
-    AutoBorrowFn(Region),
-
     /// Convert from T to *T
     AutoUnsafe(ast::Mutability),
 
@@ -430,9 +427,8 @@ pub struct BareFnTy {
 #[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct ClosureTy {
     pub fn_style: ast::FnStyle,
-    pub sigil: ast::Sigil,
     pub onceness: ast::Onceness,
-    pub region: Region,
+    pub store: TraitStore,
     pub bounds: BuiltinBounds,
     pub sig: FnSig,
 }
@@ -801,7 +797,7 @@ pub enum type_err {
     terr_onceness_mismatch(expected_found<Onceness>),
     terr_abi_mismatch(expected_found<abi::Abi>),
     terr_mutability,
-    terr_sigil_mismatch(expected_found<ast::Sigil>),
+    terr_sigil_mismatch(expected_found<TraitStore>),
     terr_box_mutability,
     terr_ptr_mutability,
     terr_ref_mutability,
@@ -1204,11 +1200,13 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
       &ty_param(_) => flags |= has_params as uint,
       &ty_infer(_) => flags |= needs_infer as uint,
       &ty_self(_) => flags |= has_self as uint,
-      &ty_enum(_, ref substs) | &ty_struct(_, ref substs) |
-      &ty_trait(~ty::TyTrait { ref substs, .. }) => {
+      &ty_enum(_, ref substs) | &ty_struct(_, ref substs) => {
+          flags |= sflags(substs);
+      }
+      &ty_trait(~ty::TyTrait { ref substs, store, .. }) => {
           flags |= sflags(substs);
-          match st {
-              ty_trait(~ty::TyTrait { store: RegionTraitStore(r, _), .. }) => {
+          match store {
+              RegionTraitStore(r, _) => {
                     flags |= rflags(r);
                 }
               _ => {}
@@ -1232,7 +1230,12 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
         flags &= !(has_ty_bot as uint);
       }
       &ty_closure(ref f) => {
-        flags |= rflags(f.region);
+        match f.store {
+            RegionTraitStore(r, _) => {
+                flags |= rflags(r);
+            }
+            _ => {}
+        }
         for a in f.sig.inputs.iter() { flags |= get(*a).flags; }
         flags |= get(f.sig.output).flags;
         // T -> _|_ is *not* _|_ !
@@ -2217,17 +2220,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
     fn closure_contents(cx: &ctxt, cty: &ClosureTy) -> TypeContents {
         // Closure contents are just like trait contents, but with potentially
         // even more stuff.
-        let st = match cty.sigil {
-            ast::BorrowedSigil =>
-                object_contents(cx, RegionTraitStore(cty.region, MutMutable), cty.bounds),
-            ast::OwnedSigil => object_contents(cx, UniqTraitStore, cty.bounds),
-            ast::ManagedSigil => unreachable!()
-        };
-
-        // FIXME(#3569): This borrowed_contents call should be taken care of in
-        // object_contents, after ~Traits and @Traits can have region bounds too.
-        // This one here is redundant for &fns but important for ~fns and @fns.
-        let rt = borrowed_contents(cty.region, ast::MutImmutable);
+        let st = object_contents(cx, cty.store, cty.bounds);
 
         // This also prohibits "@once fn" from being copied, which allows it to
         // be called. Neither way really makes much sense.
@@ -2236,7 +2229,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
             ast::Many => TC::None,
         };
 
-        st | rt | ot
+        st | ot
     }
 
     fn object_contents(cx: &ctxt,
@@ -2696,11 +2689,11 @@ pub fn ty_fn_args(fty: t) -> Vec<t> {
     }
 }
 
-pub fn ty_closure_sigil(fty: t) -> Sigil {
+pub fn ty_closure_store(fty: t) -> TraitStore {
     match get(fty).sty {
-        ty_closure(ref f) => f.sigil,
+        ty_closure(ref f) => f.store,
         ref s => {
-            fail!("ty_closure_sigil() called on non-closure type: {:?}", s)
+            fail!("ty_closure_store() called on non-closure type: {:?}", s)
         }
     }
 }
@@ -2838,15 +2831,14 @@ pub fn adjust_ty(cx: &ctxt,
     return match adjustment {
         Some(adjustment) => {
             match *adjustment {
-                AutoAddEnv(r, s) => {
+                AutoAddEnv(store) => {
                     match ty::get(unadjusted_ty).sty {
                         ty::ty_bare_fn(ref b) => {
                             ty::mk_closure(
                                 cx,
                                 ty::ClosureTy {fn_style: b.fn_style,
-                                               sigil: s,
                                                onceness: ast::Many,
-                                               region: r,
+                                               store: store,
                                                bounds: ty::AllBuiltinBounds(),
                                                sig: b.sig.clone()})
                         }
@@ -2911,10 +2903,6 @@ pub fn adjust_ty(cx: &ctxt,
                                     })
                                 }
 
-                                AutoBorrowFn(r) => {
-                                    borrow_fn(cx, span, r, adjusted_ty)
-                                }
-
                                 AutoUnsafe(m) => {
                                     mk_ptr(cx, mt {ty: adjusted_ty, mutbl: m})
                                 }
@@ -2956,25 +2944,6 @@ pub fn adjust_ty(cx: &ctxt,
         }
     }
 
-    fn borrow_fn(cx: &ctxt, span: Span, r: Region, ty: ty::t) -> ty::t {
-        match get(ty).sty {
-            ty_closure(ref fty) => {
-                ty::mk_closure(cx, ClosureTy {
-                    sigil: BorrowedSigil,
-                    region: r,
-                    ..(**fty).clone()
-                })
-            }
-
-            ref s => {
-                cx.sess.span_bug(
-                    span,
-                    format!("borrow-fn associated with bad sty: {:?}",
-                         s));
-            }
-        }
-    }
-
     fn borrow_obj(cx: &ctxt, span: Span, r: Region,
                   m: ast::Mutability, ty: ty::t) -> ty::t {
         match get(ty).sty {
@@ -2998,7 +2967,6 @@ impl AutoRef {
             ty::AutoPtr(r, m) => ty::AutoPtr(f(r), m),
             ty::AutoBorrowVec(r, m) => ty::AutoBorrowVec(f(r), m),
             ty::AutoBorrowVecRef(r, m) => ty::AutoBorrowVecRef(f(r), m),
-            ty::AutoBorrowFn(r) => ty::AutoBorrowFn(f(r)),
             ty::AutoUnsafe(m) => ty::AutoUnsafe(m),
             ty::AutoBorrowObj(r, m) => ty::AutoBorrowObj(f(r), m),
         }
@@ -4278,20 +4246,6 @@ pub fn eval_repeat_count<T: ExprTyProvider>(tcx: &T, count_expr: &ast::Expr) ->
     }
 }
 
-// Determine what the style to check a nested function under
-pub fn determine_inherited_style(parent: (ast::FnStyle, ast::NodeId),
-                                  child: (ast::FnStyle, ast::NodeId),
-                                  child_sigil: ast::Sigil)
-                                    -> (ast::FnStyle, ast::NodeId) {
-    // If the closure is a stack closure and hasn't had some non-standard
-    // style inferred for it, then check it under its parent's style.
-    // Otherwise, use its own
-    match child_sigil {
-        ast::BorrowedSigil if child.val0() == ast::NormalFn => parent,
-        _ => child
-    }
-}
-
 // Iterate over a type parameter's bounded traits and any supertraits
 // of those traits, ignoring kinds.
 // Here, the supertraits are the transitive closure of the supertrait
@@ -4640,10 +4594,16 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
             ty_closure(ref c) => {
                 byte!(15);
                 hash!(c.fn_style);
-                hash!(c.sigil);
                 hash!(c.onceness);
                 hash!(c.bounds);
-                region(&mut state, c.region);
+                match c.store {
+                    UniqTraitStore => byte!(0),
+                    RegionTraitStore(r, m) => {
+                        byte!(1)
+                        region(&mut state, r);
+                        assert_eq!(m, ast::MutMutable);
+                    }
+                }
             }
             ty_trait(~ty::TyTrait { def_id: d, store, bounds, .. }) => {
                 byte!(17);
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index a100d01f66a..840f741badb 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -56,10 +56,9 @@ pub trait TypeFolder {
                        fty: &ty::ClosureTy)
                        -> ty::ClosureTy {
         ty::ClosureTy {
-            region: self.fold_region(fty.region),
+            store: self.fold_trait_store(fty.store),
             sig: self.fold_sig(&fty.sig),
             fn_style: fty.fn_style,
-            sigil: fty.sigil,
             onceness: fty.onceness,
             bounds: fty.bounds,
         }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 3170fb82c88..99f10395437 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -112,7 +112,7 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime)
     r
 }
 
-fn opt_ast_region_to_region<AC:AstConv,RS:RegionScope>(
+pub fn opt_ast_region_to_region<AC:AstConv,RS:RegionScope>(
     this: &AC,
     rscope: &RS,
     default_span: Span,
@@ -516,33 +516,42 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                 ty::mk_bare_fn(tcx, ty_of_bare_fn(this, ast_ty.id, bf.fn_style,
                                                   bf.abi, bf.decl))
             }
-            ast::TyClosure(ref f) => {
-                if f.sigil == ast::ManagedSigil {
-                    tcx.sess.span_err(ast_ty.span,
-                                      "managed closures are not supported");
-                }
+            ast::TyClosure(ref f, ref region) => {
+
+                // resolve the function bound region in the original region
+                // scope `rscope`, not the scope of the function parameters
+                let bound_region = opt_ast_region_to_region(this, rscope,
+                                                            ast_ty.span, region);
+
+                let store = ty::RegionTraitStore(bound_region, ast::MutMutable);
+
+                // Use corresponding trait store to figure out default bounds
+                // if none were specified.
+                let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, store);
 
-                let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, match f.sigil {
-                        // Use corresponding trait store to figure out default bounds
-                        // if none were specified.
-                        ast::BorrowedSigil => {
-                            // dummy region
-                            ty::RegionTraitStore(ty::ReEmpty, ast::MutMutable)
-                        }
-                        ast::OwnedSigil    => ty::UniqTraitStore,
-                        ast::ManagedSigil  => return ty::mk_err()
-                    });
                 let fn_decl = ty_of_closure(this,
-                                            rscope,
                                             ast_ty.id,
-                                            f.sigil,
                                             f.fn_style,
                                             f.onceness,
                                             bounds,
-                                            &f.region,
+                                            store,
                                             f.decl,
-                                            None,
-                                            ast_ty.span);
+                                            None);
+                ty::mk_closure(tcx, fn_decl)
+            }
+            ast::TyProc(ref f) => {
+                // Use corresponding trait store to figure out default bounds
+                // if none were specified.
+                let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, ty::UniqTraitStore);
+
+                let fn_decl = ty_of_closure(this,
+                                            ast_ty.id,
+                                            f.fn_style,
+                                            f.onceness,
+                                            bounds,
+                                            ty::UniqTraitStore,
+                                            f.decl,
+                                            None);
                 ty::mk_closure(tcx, fn_decl)
             }
             ast::TyPath(ref path, ref bounds, id) => {
@@ -728,43 +737,19 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
     };
 }
 
-pub fn ty_of_closure<AC:AstConv,RS:RegionScope>(
+pub fn ty_of_closure<AC:AstConv>(
     this: &AC,
-    rscope: &RS,
     id: ast::NodeId,
-    sigil: ast::Sigil,
     fn_style: ast::FnStyle,
     onceness: ast::Onceness,
     bounds: ty::BuiltinBounds,
-    opt_lifetime: &Option<ast::Lifetime>,
+    store: ty::TraitStore,
     decl: &ast::FnDecl,
-    expected_sig: Option<ty::FnSig>,
-    span: Span)
+    expected_sig: Option<ty::FnSig>)
     -> ty::ClosureTy
 {
     debug!("ty_of_fn_decl");
 
-    // resolve the function bound region in the original region
-    // scope `rscope`, not the scope of the function parameters
-    let bound_region = match opt_lifetime {
-        &Some(ref lifetime) => {
-            ast_region_to_region(this.tcx(), lifetime)
-        }
-        &None => {
-            match sigil {
-                ast::OwnedSigil | ast::ManagedSigil => {
-                    // @fn(), ~fn() default to static as the bound
-                    // on their upvars:
-                    ty::ReStatic
-                }
-                ast::BorrowedSigil => {
-                    // || defaults as normal for an omitted lifetime:
-                    opt_ast_region_to_region(this, rscope, span, opt_lifetime)
-                }
-            }
-        }
-    };
-
     // new region names that appear inside of the fn decl are bound to
     // that function type
     let rb = rscope::BindingRscope::new(id);
@@ -791,9 +776,8 @@ pub fn ty_of_closure<AC:AstConv,RS:RegionScope>(
 
     ty::ClosureTy {
         fn_style: fn_style,
-        sigil: sigil,
         onceness: onceness,
-        region: bound_region,
+        store: store,
         bounds: bounds,
         sig: ty::FnSig {binder_id: id,
                         inputs: input_tys,
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 3c28f2bac27..d9f4527e9d1 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -2116,7 +2116,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
 
     fn check_expr_fn(fcx: &FnCtxt,
                      expr: &ast::Expr,
-                     ast_sigil_opt: Option<ast::Sigil>,
+                     store: ty::TraitStore,
                      decl: &ast::FnDecl,
                      body: ast::P<ast::Block>,
                      fn_kind: FnKind,
@@ -2126,18 +2126,11 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
         // Find the expected input/output types (if any). Substitute
         // fresh bound regions for any bound regions we find in the
         // expected types so as to avoid capture.
-        //
-        // Also try to pick up inferred style and sigil, defaulting
-        // to impure and block. Note that we only will use those for
-        // block syntax lambdas; that is, lambdas without explicit
-        // sigils.
         let expected_sty = unpack_expected(fcx,
                                            expected,
                                            |x| Some((*x).clone()));
         let error_happened = false;
         let (expected_sig,
-             expected_style,
-             expected_sigil,
              expected_onceness,
              expected_bounds) = {
             match expected_sty {
@@ -2146,47 +2139,32 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                         replace_late_bound_regions_in_fn_sig(
                             tcx, &cenv.sig,
                             |_| fcx.inh.infcx.fresh_bound_region(expr.id));
-                    (Some(sig), cenv.fn_style, cenv.sigil,
-                     cenv.onceness, cenv.bounds)
+                    (Some(sig), cenv.onceness, cenv.bounds)
                 }
                 _ => {
                     // Not an error! Means we're inferring the closure type
-                    let mut sigil = ast::BorrowedSigil;
-                    let mut onceness = ast::Many;
                     let mut bounds = ty::EmptyBuiltinBounds();
-                    match expr.node {
+                    let onceness = match expr.node {
                         ast::ExprProc(..) => {
-                            sigil = ast::OwnedSigil;
-                            onceness = ast::Once;
                             bounds.add(ty::BoundSend);
+                            ast::Once
                         }
-                        _ => ()
-                    }
-                    (None, ast::NormalFn, sigil,
-                     onceness, bounds)
+                        _ => ast::Many
+                    };
+                    (None, onceness, bounds)
                 }
             }
         };
 
-        // If the proto is specified, use that, otherwise select a
-        // proto based on inference.
-        let (sigil, fn_style) = match ast_sigil_opt {
-            Some(p) => (p, ast::NormalFn),
-            None => (expected_sigil, expected_style)
-        };
-
         // construct the function type
         let fn_ty = astconv::ty_of_closure(fcx,
-                                           fcx.infcx(),
                                            expr.id,
-                                           sigil,
-                                           fn_style,
+                                           ast::NormalFn,
                                            expected_onceness,
                                            expected_bounds,
-                                           &None,
+                                           store,
                                            decl,
-                                           expected_sig,
-                                           expr.span);
+                                           expected_sig);
 
         let fty_sig;
         let fty = if error_happened {
@@ -2198,9 +2176,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
             };
             ty::mk_err()
         } else {
-            let fn_ty_copy = fn_ty.clone();
             fty_sig = fn_ty.sig.clone();
-            ty::mk_closure(tcx, fn_ty_copy)
+            ty::mk_closure(tcx, fn_ty.clone())
         };
 
         debug!("check_expr_fn_with_unifier fty={}",
@@ -2208,11 +2185,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
 
         fcx.write_ty(expr.id, fty);
 
-        let (inherited_style, id) =
-            ty::determine_inherited_style((fcx.ps.borrow().fn_style,
-                                            fcx.ps.borrow().def),
-                                           (fn_style, expr.id),
-                                           sigil);
+        // If the closure is a stack closure and hasn't had some non-standard
+        // style inferred for it, then check it under its parent's style.
+        // Otherwise, use its own
+        let (inherited_style, id) = match store {
+            ty::RegionTraitStore(..) => (fcx.ps.borrow().fn_style,
+                                         fcx.ps.borrow().def),
+            ty::UniqTraitStore => (ast::NormalFn, expr.id)
+        };
 
         check_fn(fcx.ccx, inherited_style, &fty_sig,
                  decl, id, body, fn_kind, fcx.inh);
@@ -2856,9 +2836,13 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
         _match::check_match(fcx, expr, discrim, arms.as_slice());
       }
       ast::ExprFnBlock(decl, body) => {
+        let region = astconv::opt_ast_region_to_region(fcx,
+                                                       fcx.infcx(),
+                                                       expr.span,
+                                                       &None);
         check_expr_fn(fcx,
                       expr,
-                      Some(ast::BorrowedSigil),
+                      ty::RegionTraitStore(region, ast::MutMutable),
                       decl,
                       body,
                       Vanilla,
@@ -2867,7 +2851,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
       ast::ExprProc(decl, body) => {
         check_expr_fn(fcx,
                       expr,
-                      Some(ast::OwnedSigil),
+                      ty::UniqTraitStore,
                       decl,
                       body,
                       Vanilla,
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index d1a6c069f23..9e7bb1b10f6 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -133,7 +133,6 @@ use middle::typeck::MethodCall;
 use middle::pat_util;
 use util::ppaux::{ty_to_str, region_to_str, Repr};
 
-use syntax::ast::{ManagedSigil, OwnedSigil, BorrowedSigil};
 use syntax::ast::{DefArg, DefBinding, DefLocal, DefUpvar};
 use syntax::ast;
 use syntax::ast_util;
@@ -175,9 +174,9 @@ fn region_of_def(fcx: &FnCtxt, def: ast::Def) -> ty::Region {
             tcx.region_maps.var_region(node_id)
         }
         DefUpvar(_, subdef, closure_id, body_id) => {
-            match ty::ty_closure_sigil(fcx.node_ty(closure_id)) {
-                BorrowedSigil => region_of_def(fcx, *subdef),
-                ManagedSigil | OwnedSigil => ReScope(body_id)
+            match ty::ty_closure_store(fcx.node_ty(closure_id)) {
+                ty::RegionTraitStore(..) => region_of_def(fcx, *subdef),
+                ty::UniqTraitStore => ReScope(body_id)
             }
         }
         _ => {
@@ -611,7 +610,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
     let function_type = rcx.resolve_node_type(expr.id);
     match ty::get(function_type).sty {
         ty::ty_closure(~ty::ClosureTy {
-                sigil: ast::BorrowedSigil, region: region, ..}) => {
+                store: ty::RegionTraitStore(region, _), ..}) => {
             let freevars = freevars::get_freevars(tcx, expr.id);
             if freevars.is_empty() {
                 // No free variables means that the environment
@@ -635,7 +634,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
     rcx.set_repeating_scope(repeating_scope);
 
     match ty::get(function_type).sty {
-        ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil, ..}) => {
+        ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(..), ..}) => {
             let freevars = freevars::get_freevars(tcx, expr.id);
             propagate_upupvar_borrow_kind(rcx, expr, freevars);
         }
@@ -749,8 +748,12 @@ fn constrain_callee(rcx: &mut Rcx,
     match ty::get(callee_ty).sty {
         ty::ty_bare_fn(..) => { }
         ty::ty_closure(ref closure_ty) => {
+            let region = match closure_ty.store {
+                ty::RegionTraitStore(r, _) => r,
+                ty::UniqTraitStore => ty::ReStatic
+            };
             rcx.fcx.mk_subr(true, infer::InvokeClosure(callee_expr.span),
-                            call_region, closure_ty.region);
+                            call_region, region);
         }
         _ => {
             // this should not happen, but it does if the program is
@@ -1120,13 +1123,8 @@ fn link_autoref(rcx: &mut Rcx,
             link_region(mc.typer, expr.span, r, m, cmt_index);
         }
 
-        ty::AutoBorrowFn(r) => {
-            let cmt_deref = mc.cat_deref_fn_or_obj(expr, expr_cmt, 0);
-            link_region(mc.typer, expr.span, r, ast::MutImmutable, cmt_deref);
-        }
-
         ty::AutoBorrowObj(r, m) => {
-            let cmt_deref = mc.cat_deref_fn_or_obj(expr, expr_cmt, 0);
+            let cmt_deref = mc.cat_deref_obj(expr, expr_cmt);
             link_region(mc.typer, expr.span, r, m, cmt_deref);
         }
 
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index 7159febc7f1..6ad3d380b28 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -141,7 +141,11 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
 
         Some(adjustment) => {
             match *adjustment {
-                ty::AutoAddEnv(r, s) => {
+                ty::AutoAddEnv(store) => {
+                    let r = match store {
+                        ty::RegionTraitStore(r, _) => r,
+                        ty::UniqTraitStore => ty::ReStatic
+                    };
                     match resolve_region(fcx.infcx(),
                                          r,
                                          resolve_all | force_all) {
@@ -166,7 +170,12 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
                                         "cannot coerce non-statically resolved bare fn")
                             }
 
-                            let resolved_adj = @ty::AutoAddEnv(r1, s);
+                            let resolved_adj = @ty::AutoAddEnv(match store {
+                                ty::RegionTraitStore(..) => {
+                                    ty::RegionTraitStore(r1, ast::MutMutable)
+                                }
+                                ty::UniqTraitStore => ty::UniqTraitStore
+                            });
                             debug!("Adjustments for node {}: {:?}",
                                    id, resolved_adj);
                             tcx.adjustments.borrow_mut().insert(id, resolved_adj);
diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs
index d76bfed661e..7d1ffa4451f 100644
--- a/src/librustc/middle/typeck/infer/coercion.rs
+++ b/src/librustc/middle/typeck/infer/coercion.rs
@@ -65,8 +65,7 @@ we may want to adjust precisely when coercions occur.
 */
 
 
-use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowFn, AutoBorrowObj};
-use middle::ty::{AutoDerefRef};
+use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowObj, AutoDerefRef};
 use middle::ty::{VstoreSlice, VstoreUniq};
 use middle::ty::{mt};
 use middle::ty;
@@ -120,7 +119,7 @@ impl<'f> Coerce<'f> {
                 });
             }
 
-            ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil, ..}) => {
+            ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(..), ..}) => {
                 return self.unpack_actual_value(a, |sty_a| {
                     self.coerce_borrowed_fn(a, sty_a, b)
                 });
@@ -342,33 +341,14 @@ impl<'f> Coerce<'f> {
                a.inf_str(self.get_ref().infcx), sty_a,
                b.inf_str(self.get_ref().infcx));
 
-        let fn_ty = match *sty_a {
-            ty::ty_closure(ref f) if f.sigil == ast::ManagedSigil ||
-                                     f.sigil == ast::OwnedSigil => {
-                (*f).clone()
-            }
+        match *sty_a {
             ty::ty_bare_fn(ref f) => {
-                return self.coerce_from_bare_fn(a, f, b);
+                self.coerce_from_bare_fn(a, f, b)
             }
             _ => {
-                return self.subtype(a, b);
+                self.subtype(a, b)
             }
-        };
-
-        let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
-        let a_borrowed = ty::mk_closure(
-            self.get_ref().infcx.tcx,
-            ty::ClosureTy {
-                sigil: ast::BorrowedSigil,
-                region: r_borrow,
-                .. *fn_ty
-            });
-
-        if_ok!(self.subtype(a_borrowed, b));
-        Ok(Some(@AutoDerefRef(AutoDerefRef {
-            autoderefs: 0,
-            autoref: Some(AutoBorrowFn(r_borrow))
-        })))
+        }
     }
 
     fn coerce_from_bare_fn(&self, a: ty::t, fn_ty_a: &ty::BareFnTy, b: ty::t)
@@ -393,7 +373,7 @@ impl<'f> Coerce<'f> {
                 _ => return self.subtype(a, b)
             };
 
-            let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
+            let adj = @ty::AutoAddEnv(fn_ty_b.store);
             let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
                                            ty::ClosureTy {
                                                 sig: fn_ty_a.sig.clone(),
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index a2a7f9ec8bd..8c449a8f118 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -205,18 +205,32 @@ pub trait Combine {
     fn closure_tys(&self, a: &ty::ClosureTy,
                    b: &ty::ClosureTy) -> cres<ty::ClosureTy> {
 
-        let p = if_ok!(self.sigils(a.sigil, b.sigil));
-        let r = if_ok!(self.contraregions(a.region, b.region));
+        let store = match (a.store, b.store) {
+            (ty::RegionTraitStore(a_r, a_m),
+             ty::RegionTraitStore(b_r, b_m)) if a_m == b_m => {
+                let r = if_ok!(self.contraregions(a_r, b_r));
+                ty::RegionTraitStore(r, a_m)
+            }
+
+            _ if a.store == b.store => {
+                a.store
+            }
+
+            _ => {
+                return Err(ty::terr_sigil_mismatch(expected_found(self, a.store, b.store)))
+            }
+        };
         let fn_style = if_ok!(self.fn_styles(a.fn_style, b.fn_style));
         let onceness = if_ok!(self.oncenesses(a.onceness, b.onceness));
         let bounds = if_ok!(self.bounds(a.bounds, b.bounds));
         let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig));
-        Ok(ty::ClosureTy {fn_style: fn_style,
-                sigil: p,
-                onceness: onceness,
-                region: r,
-                bounds: bounds,
-                sig: sig})
+        Ok(ty::ClosureTy {
+            fn_style: fn_style,
+            onceness: onceness,
+            store: store,
+            bounds: bounds,
+            sig: sig
+        })
     }
 
     fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig>;
@@ -238,14 +252,6 @@ pub trait Combine {
         self.contratys(a, b).and_then(|t| Ok(t))
     }
 
-    fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
-        if p1 == p2 {
-            Ok(p1)
-        } else {
-            Err(ty::terr_sigil_mismatch(expected_found(self, p1, p2)))
-        }
-    }
-
     fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<FnStyle>;
 
     fn abi(&self, a: abi::Abi, b: abi::Abi) -> cres<abi::Abi> {
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index a0817360e39..c6c79608f6c 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -704,11 +704,13 @@ impl<'a> ConstraintContext<'a> {
                 self.add_constraint(index, variance);
             }
 
-            ty::ty_bare_fn(ty::BareFnTy { sig: ref sig, .. }) => {
+            ty::ty_bare_fn(ty::BareFnTy { ref sig, .. }) |
+            ty::ty_closure(~ty::ClosureTy { ref sig, store: ty::UniqTraitStore, .. }) => {
                 self.add_constraints_from_sig(sig, variance);
             }
 
-            ty::ty_closure(~ty::ClosureTy { sig: ref sig, region, .. }) => {
+            ty::ty_closure(~ty::ClosureTy { ref sig,
+                    store: ty::RegionTraitStore(region, _), .. }) => {
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(region, contra);
                 self.add_constraints_from_sig(sig, variance);
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 3bb344548e1..63ea1a5ec86 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -266,21 +266,11 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
     }
 
     fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> ~str {
-        let is_proc =
-            (cty.sigil, cty.onceness) == (ast::OwnedSigil, ast::Once);
-        let is_borrowed_closure = cty.sigil == ast::BorrowedSigil;
+        let mut s = StrBuf::new();
 
-        let mut s = if is_proc || is_borrowed_closure {
-            StrBuf::new()
-        } else {
-            StrBuf::from_owned_str(cty.sigil.to_str())
-        };
-
-        match (cty.sigil, cty.region) {
-            (ast::ManagedSigil, ty::ReStatic) |
-            (ast::OwnedSigil, ty::ReStatic) => {}
-
-            (_, region) => {
+        match cty.store {
+            ty::UniqTraitStore => {}
+            ty::RegionTraitStore(region, _) => {
                 s.push_str(region_to_str(cx, "", true, region));
             }
         }
@@ -293,40 +283,24 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
             }
         };
 
-        if is_proc {
-            s.push_str("proc");
-        } else {
-            match cty.onceness {
-                ast::Many => {}
-                ast::Once => {
-                    s.push_str(cty.onceness.to_str());
-                    s.push_char(' ');
+        match cty.store {
+            ty::UniqTraitStore => {
+                assert_eq!(cty.onceness, ast::Once);
+                s.push_str("proc");
+                push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
+            }
+            ty::RegionTraitStore(..) => {
+                match cty.onceness {
+                    ast::Many => {}
+                    ast::Once => s.push_str("once ")
                 }
-            };
-
-            if !is_borrowed_closure {
-                s.push_str("fn");
+                push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
             }
         }
 
-        if !is_borrowed_closure {
-            // Print bounds before `fn` if this is not a borrowed closure.
-            if !cty.bounds.is_empty() {
-                s.push_str(":");
-                s.push_str(cty.bounds.repr(cx));
-            }
-
-            push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
-        } else {
-            // Print bounds after the signature if this is a borrowed closure.
-            push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
-
-            if is_borrowed_closure {
-                if !cty.bounds.is_empty() {
-                    s.push_str(":");
-                    s.push_str(cty.bounds.repr(cx));
-                }
-            }
+        if !cty.bounds.is_empty() {
+            s.push_str(":");
+            s.push_str(cty.bounds.repr(cx));
         }
 
         s.into_owned()
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index 7430c7ccb49..32a61fcca07 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -474,8 +474,6 @@ impl Clean<Item> for doctree::Function {
 
 #[deriving(Clone, Encodable, Decodable)]
 pub struct ClosureDecl {
-    pub sigil: ast::Sigil,
-    pub region: Option<Lifetime>,
     pub lifetimes: Vec<Lifetime>,
     pub decl: FnDecl,
     pub onceness: ast::Onceness,
@@ -486,8 +484,6 @@ pub struct ClosureDecl {
 impl Clean<ClosureDecl> for ast::ClosureTy {
     fn clean(&self) -> ClosureDecl {
         ClosureDecl {
-            sigil: self.sigil,
-            region: self.region.clean(),
             lifetimes: self.lifetimes.clean().move_iter().collect(),
             decl: self.decl.clean(),
             onceness: self.onceness,
@@ -652,7 +648,8 @@ pub enum Type {
     Self(ast::NodeId),
     /// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
     Primitive(ast::PrimTy),
-    Closure(~ClosureDecl),
+    Closure(~ClosureDecl, Option<Lifetime>),
+    Proc(~ClosureDecl),
     /// extern "ABI" fn
     BareFunction(~BareFunctionDecl),
     Tuple(Vec<Type> ),
@@ -706,7 +703,8 @@ impl Clean<Type> for ast::Ty {
                              tpbs.clean().map(|x| x.move_iter().collect()),
                              id)
             }
-            TyClosure(ref c) => Closure(~c.clean()),
+            TyClosure(ref c, region) => Closure(~c.clean(), region.clean()),
+            TyProc(ref c) => Proc(~c.clean()),
             TyBareFn(ref barefn) => BareFunction(~barefn.clean()),
             TyBot => Bottom,
             ref x => fail!("Unimplemented type {:?}", x),
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 9daa135647f..66edbf82017 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -337,19 +337,24 @@ impl fmt::Show for clean::Type {
                 };
                 f.buf.write(s.as_bytes())
             }
-            clean::Closure(ref decl) => {
-                let region = match decl.region {
+            clean::Closure(ref decl, ref region) => {
+                let region = match *region {
                     Some(ref region) => format!("{} ", *region),
                     None => ~"",
                 };
 
-                write!(f.buf, "{}{}{arrow, select, yes{ -&gt; {ret}} other{}}",
+                write!(f.buf, "{}{}|{}|{arrow, select, yes{ -&gt; {ret}} other{}}",
                        FnStyleSpace(decl.fn_style),
-                       match decl.sigil {
-                           ast::OwnedSigil => format!("proc({})", decl.decl.inputs),
-                           ast::BorrowedSigil => format!("{}|{}|", region, decl.decl.inputs),
-                           ast::ManagedSigil => format!("@{}fn({})", region, decl.decl.inputs),
-                       },
+                       region,
+                       decl.decl.inputs,
+                       arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
+                       ret = decl.decl.output)
+                // FIXME: where are bounds and lifetimes printed?!
+            }
+            clean::Proc(ref decl) => {
+                write!(f.buf, "{}proc({}){arrow, select, yes{ -&gt; {ret}} other{}}",
+                       FnStyleSpace(decl.fn_style),
+                       decl.decl.inputs,
                        arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
                        ret = decl.decl.output)
                 // FIXME: where are bounds and lifetimes printed?!
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 1eb034a573a..a27a419e7be 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -360,23 +360,6 @@ pub enum Mutability {
 }
 
 #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
-pub enum Sigil {
-    BorrowedSigil,
-    OwnedSigil,
-    ManagedSigil
-}
-
-impl fmt::Show for Sigil {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            BorrowedSigil => "&".fmt(f),
-            OwnedSigil => "~".fmt(f),
-            ManagedSigil => "@".fmt(f),
-         }
-    }
-}
-
-#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum ExprVstore {
     ExprVstoreUniq,                 // ~[1,2,3,4]
     ExprVstoreSlice,                // &[1,2,3,4]
@@ -791,8 +774,6 @@ impl fmt::Show for Onceness {
 
 #[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct ClosureTy {
-    pub sigil: Sigil,
-    pub region: Option<Lifetime>,
     pub lifetimes: Vec<Lifetime>,
     pub fn_style: FnStyle,
     pub onceness: Onceness,
@@ -822,7 +803,8 @@ pub enum Ty_ {
     TyFixedLengthVec(P<Ty>, @Expr),
     TyPtr(MutTy),
     TyRptr(Option<Lifetime>, MutTy),
-    TyClosure(@ClosureTy),
+    TyClosure(@ClosureTy, Option<Lifetime>),
+    TyProc(@ClosureTy),
     TyBareFn(@BareFnTy),
     TyTup(Vec<P<Ty>> ),
     TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index e9e69eabef8..63df5566fa5 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -155,11 +155,18 @@ pub trait Folder {
             TyRptr(ref region, ref mt) => {
                 TyRptr(fold_opt_lifetime(region, self), fold_mt(mt, self))
             }
-            TyClosure(ref f) => {
+            TyClosure(ref f, ref region) => {
                 TyClosure(@ClosureTy {
-                    sigil: f.sigil,
                     fn_style: f.fn_style,
-                    region: fold_opt_lifetime(&f.region, self),
+                    onceness: f.onceness,
+                    bounds: fold_opt_bounds(&f.bounds, self),
+                    decl: self.fold_fn_decl(f.decl),
+                    lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(),
+                }, fold_opt_lifetime(region, self))
+            }
+            TyProc(ref f) => {
+                TyProc(@ClosureTy {
+                    fn_style: f.fn_style,
                     onceness: f.onceness,
                     bounds: fold_opt_bounds(&f.bounds, self),
                     decl: self.fold_fn_decl(f.decl),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 6bc325bffcc..88480c1b336 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -11,7 +11,6 @@
 #![macro_escape]
 
 use abi;
-use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
 use ast::{BareFnTy, ClosureTy};
 use ast::{RegionTyParamBound, TraitTyParamBound};
 use ast::{Provided, Public, FnStyle};
@@ -49,8 +48,8 @@ use ast::StrStyle;
 use ast::{SelfRegion, SelfStatic, SelfUniq, SelfValue};
 use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
-use ast::{TypeField, TyFixedLengthVec, TyClosure, TyBareFn, TyTypeof};
-use ast::{TyInfer, TypeMethod};
+use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
+use ast::{TyTypeof, TyInfer, TypeMethod};
 use ast::{TyNil, TyParam, TyParamBound, TyPath, TyPtr, TyRptr};
 use ast::{TyTup, TyU32, TyUniq, TyVec, UnUniq};
 use ast::{UnnamedField, UnsafeBlock, UnsafeFn, ViewItem};
@@ -923,9 +922,7 @@ impl<'a> Parser<'a> {
             cf: ret_style,
             variadic: variadic
         });
-        TyClosure(@ClosureTy {
-            sigil: OwnedSigil,
-            region: None,
+        TyProc(@ClosureTy {
             fn_style: NormalFn,
             onceness: Once,
             bounds: bounds,
@@ -984,14 +981,12 @@ impl<'a> Parser<'a> {
         });
 
         TyClosure(@ClosureTy {
-            sigil: BorrowedSigil,
-            region: region,
             fn_style: fn_style,
             onceness: onceness,
             bounds: bounds,
             decl: decl,
             lifetimes: lifetimes,
-        })
+        }, region)
     }
 
     pub fn parse_unsafety(&mut self) -> FnStyle {
@@ -1201,11 +1196,11 @@ impl<'a> Parser<'a> {
         } else if self.token == token::AT {
             // MANAGED POINTER
             self.bump();
-            self.parse_box_or_uniq_pointee(ManagedSigil)
+            TyBox(self.parse_ty(false))
         } else if self.token == token::TILDE {
             // OWNED POINTER
             self.bump();
-            self.parse_box_or_uniq_pointee(OwnedSigil)
+            TyUniq(self.parse_ty(false))
         } else if self.token == token::BINOP(token::STAR) {
             // STAR POINTER (bare pointer?)
             self.bump();
@@ -1271,21 +1266,6 @@ impl<'a> Parser<'a> {
         P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp})
     }
 
-    // parse the type following a @ or a ~
-    pub fn parse_box_or_uniq_pointee(&mut self,
-                                     sigil: ast::Sigil)
-                                     -> Ty_ {
-        // other things are parsed as @/~ + a type.  Note that constructs like
-        // ~[] and ~str will be resolved during typeck to slices and so forth,
-        // rather than boxed ptrs.  But the special casing of str/vec is not
-        // reflected in the AST type.
-        if sigil == OwnedSigil {
-            TyUniq(self.parse_ty(false))
-        } else {
-            TyBox(self.parse_ty(false))
-        }
-    }
-
     pub fn parse_borrowed_pointee(&mut self) -> Ty_ {
         // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
         let opt_lifetime = self.parse_opt_lifetime();
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 3e2509f4f6e..4d911f6a89b 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -483,14 +483,23 @@ impl<'a> State<'a> {
                                    f.fn_style, ast::Many, f.decl, None, &None,
                                    Some(&generics), None));
             }
-            ast::TyClosure(f) => {
+            ast::TyClosure(f, ref region) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
                     ty_params: OwnedSlice::empty()
                 };
-                try!(self.print_ty_fn(None, Some(f.sigil), &f.region,
-                                   f.fn_style, f.onceness, f.decl, None, &f.bounds,
-                                   Some(&generics), None));
+                try!(self.print_ty_fn(None, Some('&'), region, f.fn_style,
+                                      f.onceness, f.decl, None, &f.bounds,
+                                      Some(&generics), None));
+            }
+            ast::TyProc(f) => {
+                let generics = ast::Generics {
+                    lifetimes: f.lifetimes.clone(),
+                    ty_params: OwnedSlice::empty()
+                };
+                try!(self.print_ty_fn(None, Some('~'), &None, f.fn_style,
+                                      f.onceness, f.decl, None, &f.bounds,
+                                      Some(&generics), None));
             }
             ast::TyPath(ref path, ref bounds, _) => {
                 try!(self.print_bounded_path(path, bounds));
@@ -1716,8 +1725,7 @@ impl<'a> State<'a> {
                     opt_explicit_self: Option<ast::ExplicitSelf_>,
                     vis: ast::Visibility) -> IoResult<()> {
         try!(self.head(""));
-        try!(self.print_fn_header_info(opt_explicit_self, fn_style, abi,
-                                       ast::Many, None, vis));
+        try!(self.print_fn_header_info(opt_explicit_self, fn_style, abi, vis));
         try!(self.nbsp());
         try!(self.print_ident(name));
         try!(self.print_generics(generics));
@@ -2023,7 +2031,7 @@ impl<'a> State<'a> {
 
     pub fn print_ty_fn(&mut self,
                        opt_abi: Option<abi::Abi>,
-                       opt_sigil: Option<ast::Sigil>,
+                       opt_sigil: Option<char>,
                        opt_region: &Option<ast::Lifetime>,
                        fn_style: ast::FnStyle,
                        onceness: ast::Onceness,
@@ -2037,15 +2045,15 @@ impl<'a> State<'a> {
 
         // Duplicates the logic in `print_fn_header_info()`.  This is because that
         // function prints the sigil in the wrong place.  That should be fixed.
-        if opt_sigil == Some(ast::OwnedSigil) && onceness == ast::Once {
+        if opt_sigil == Some('~') && onceness == ast::Once {
             try!(word(&mut self.s, "proc"));
-        } else if opt_sigil == Some(ast::BorrowedSigil) {
+        } else if opt_sigil == Some('&') {
             try!(self.print_extern_opt_abi(opt_abi));
             try!(self.print_fn_style(fn_style));
             try!(self.print_onceness(onceness));
         } else {
+            assert!(opt_sigil.is_none());
             try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
-            try!(self.print_opt_sigil(opt_sigil));
             try!(self.print_fn_style(fn_style));
             try!(self.print_onceness(onceness));
             try!(word(&mut self.s, "fn"));
@@ -2062,7 +2070,7 @@ impl<'a> State<'a> {
         match generics { Some(g) => try!(self.print_generics(g)), _ => () }
         try!(zerobreak(&mut self.s));
 
-        if opt_sigil == Some(ast::BorrowedSigil) {
+        if opt_sigil == Some('&') {
             try!(word(&mut self.s, "|"));
         } else {
             try!(self.popen());
@@ -2070,7 +2078,7 @@ impl<'a> State<'a> {
 
         try!(self.print_fn_args(decl, opt_explicit_self));
 
-        if opt_sigil == Some(ast::BorrowedSigil) {
+        if opt_sigil == Some('&') {
             try!(word(&mut self.s, "|"));
         } else {
             if decl.variadic {
@@ -2327,22 +2335,10 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_opt_sigil(&mut self,
-                           opt_sigil: Option<ast::Sigil>) -> IoResult<()> {
-        match opt_sigil {
-            Some(ast::BorrowedSigil) => word(&mut self.s, "&"),
-            Some(ast::OwnedSigil) => word(&mut self.s, "~"),
-            Some(ast::ManagedSigil) => word(&mut self.s, "@"),
-            None => Ok(())
-        }
-    }
-
     pub fn print_fn_header_info(&mut self,
                                 _opt_explicit_self: Option<ast::ExplicitSelf_>,
                                 opt_fn_style: Option<ast::FnStyle>,
                                 abi: abi::Abi,
-                                onceness: ast::Onceness,
-                                opt_sigil: Option<ast::Sigil>,
                                 vis: ast::Visibility) -> IoResult<()> {
         try!(word(&mut self.s, visibility_qualified(vis, "")));
 
@@ -2357,9 +2353,7 @@ impl<'a> State<'a> {
             try!(self.print_opt_fn_style(opt_fn_style));
         }
 
-        try!(self.print_onceness(onceness));
-        try!(word(&mut self.s, "fn"));
-        self.print_opt_sigil(opt_sigil)
+        word(&mut self.s, "fn")
     }
 
     pub fn print_fn_style(&mut self, s: ast::FnStyle) -> IoResult<()> {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 5b376f4c5fe..266de67b81d 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -328,7 +328,7 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
                 visitor.visit_ty(tuple_element_type, env.clone())
             }
         }
-        TyClosure(ref function_declaration) => {
+        TyClosure(ref function_declaration, ref region) => {
             for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(argument.ty, env.clone())
             }
@@ -338,11 +338,22 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
             }
             visitor.visit_opt_lifetime_ref(
                 typ.span,
-                &function_declaration.region,
+                region,
                 env.clone());
             walk_lifetime_decls(visitor, &function_declaration.lifetimes,
                                 env.clone());
         }
+        TyProc(ref function_declaration) => {
+            for argument in function_declaration.decl.inputs.iter() {
+                visitor.visit_ty(argument.ty, env.clone())
+            }
+            visitor.visit_ty(function_declaration.decl.output, env.clone());
+            for bounds in function_declaration.bounds.iter() {
+                walk_ty_param_bounds(visitor, bounds, env.clone())
+            }
+            walk_lifetime_decls(visitor, &function_declaration.lifetimes,
+                                env.clone());
+        }
         TyBareFn(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(argument.ty, env.clone())