about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-04-24 01:29:46 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-04-29 14:30:55 -0700
commitf30f54e9d062bdb5b3cb10dd7185470280c1c278 (patch)
treeb641e10eb9ee445b023d9d9b69ea8330c41ca30b
parenta12a3db5b44d539f5512376a2e7bb40fbab63683 (diff)
downloadrust-f30f54e9d062bdb5b3cb10dd7185470280c1c278.tar.gz
rust-f30f54e9d062bdb5b3cb10dd7185470280c1c278.zip
librustc: Remove the concept of modes from the compiler.
This commit does not remove `ty::arg`, although that should be
possible to do now.
-rw-r--r--src/librustc/metadata/common.rs1
-rw-r--r--src/librustc/metadata/decoder.rs4
-rw-r--r--src/librustc/metadata/tydecode.rs16
-rw-r--r--src/librustc/metadata/tyencode.rs8
-rw-r--r--src/librustc/middle/astencode.rs32
-rw-r--r--src/librustc/middle/borrowck/gather_loans.rs32
-rw-r--r--src/librustc/middle/lint.rs159
-rw-r--r--src/librustc/middle/liveness.rs93
-rw-r--r--src/librustc/middle/mem_categorization.rs7
-rw-r--r--src/librustc/middle/moves.rs37
-rw-r--r--src/librustc/middle/resolve.rs12
-rw-r--r--src/librustc/middle/trans/asm.rs27
-rw-r--r--src/librustc/middle/trans/base.rs33
-rw-r--r--src/librustc/middle/trans/callee.rs68
-rw-r--r--src/librustc/middle/trans/expr.rs2
-rw-r--r--src/librustc/middle/trans/foreign.rs9
-rw-r--r--src/librustc/middle/trans/meth.rs35
-rw-r--r--src/librustc/middle/trans/reflect.rs20
-rw-r--r--src/librustc/middle/trans/type_of.rs7
-rw-r--r--src/librustc/middle/trans/type_use.rs26
-rw-r--r--src/librustc/middle/ty.rs151
-rw-r--r--src/librustc/middle/typeck/astconv.rs56
-rw-r--r--src/librustc/middle/typeck/check/method.rs11
-rw-r--r--src/librustc/middle/typeck/check/mod.rs453
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs2
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs64
-rw-r--r--src/librustc/middle/typeck/collect.rs8
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs31
-rw-r--r--src/librustc/middle/typeck/infer/glb.rs4
-rw-r--r--src/librustc/middle/typeck/infer/lub.rs4
-rw-r--r--src/librustc/middle/typeck/infer/sub.rs6
-rw-r--r--src/librustc/middle/typeck/mod.rs30
-rw-r--r--src/librustc/util/ppaux.rs41
-rw-r--r--src/libsyntax/ast.rs40
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/ext/auto_encode.rs30
-rw-r--r--src/libsyntax/ext/build.rs1
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs1
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs62
-rw-r--r--src/libsyntax/print/pprust.rs14
41 files changed, 557 insertions, 1083 deletions
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index e2672338a8a..8e689f3147b 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -128,7 +128,6 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
     tag_table_freevars = 0x59,
     tag_table_tcache = 0x5a,
     tag_table_param_defs = 0x5b,
-    tag_table_inferred_modes = 0x5c,
     tag_table_mutbl = 0x5d,
     tag_table_last_use = 0x5e,
     tag_table_spill = 0x5f,
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 1a94b57279c..cfe31360d32 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -244,8 +244,8 @@ fn doc_transformed_self_ty(doc: ebml::Doc,
     }
 }
 
-pub fn item_type(_item_id: ast::def_id, item: ebml::Doc,
-                 tcx: ty::ctxt, cdata: cmd) -> ty::t {
+pub fn item_type(_: ast::def_id, item: ebml::Doc, tcx: ty::ctxt, cdata: cmd)
+                 -> ty::t {
     doc_type(item, tcx, cdata)
 }
 
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index bb8c93a9d5d..011ee115e8c 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -469,16 +469,9 @@ fn parse_onceness(c: char) -> ast::Onceness {
 }
 
 fn parse_arg(st: @mut PState, conv: conv_did) -> ty::arg {
-    ty::arg { mode: parse_mode(st), ty: parse_ty(st, conv) }
-}
-
-fn parse_mode(st: @mut PState) -> ast::mode {
-    let m = ast::expl(match next(st) {
-        '+' => ast::by_copy,
-        '=' => ast::by_ref,
-        _ => fail!(~"bad mode")
-    });
-    return m;
+    ty::arg {
+        ty: parse_ty(st, conv)
+    }
 }
 
 fn parse_closure_ty(st: @mut PState, conv: conv_did) -> ty::ClosureTy {
@@ -511,8 +504,7 @@ fn parse_sig(st: @mut PState, conv: conv_did) -> ty::FnSig {
     assert!((next(st) == '['));
     let mut inputs: ~[ty::arg] = ~[];
     while peek(st) != ']' {
-        let mode = parse_mode(st);
-        inputs.push(ty::arg { mode: mode, ty: parse_ty(st, conv) });
+        inputs.push(ty::arg { ty: parse_ty(st, conv) });
     }
     st.pos += 1u; // eat the ']'
     let ret_ty = parse_ty(st, conv);
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 7c9de2d0b41..763b1984b81 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -344,17 +344,9 @@ fn enc_sigil(w: @io::Writer, sigil: Sigil) {
 }
 
 pub fn enc_arg(w: @io::Writer, cx: @ctxt, arg: ty::arg) {
-    enc_mode(w, cx, arg.mode);
     enc_ty(w, cx, arg.ty);
 }
 
-pub fn enc_mode(w: @io::Writer, cx: @ctxt, m: mode) {
-    match ty::resolved_mode(cx.tcx, m) {
-      by_copy => w.write_char('+'),
-      by_ref => w.write_char('='),
-    }
-}
-
 fn enc_purity(w: @io::Writer, p: purity) {
     match p {
       pure_fn => w.write_char('p'),
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index f1fd1cd7242..c7c9c110586 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -410,7 +410,7 @@ impl tr for ast::def {
           ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) }
           ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) }
           ast::def_const(did) => { ast::def_const(did.tr(xcx)) }
-          ast::def_arg(nid, m, b) => { ast::def_arg(xcx.tr_id(nid), m, b) }
+          ast::def_arg(nid, b) => { ast::def_arg(xcx.tr_id(nid), b) }
           ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) }
           ast::def_variant(e_did, v_did) => {
             ast::def_variant(e_did.tr(xcx), v_did.tr(xcx))
@@ -571,6 +571,9 @@ fn encode_method_map_entry(ecx: @e::EncodeContext,
         do ebml_w.emit_field(~"origin", 1u) {
             mme.origin.encode(ebml_w);
         }
+        do ebml_w.emit_field(~"self_mode", 3) {
+            mme.self_mode.encode(ebml_w);
+        }
     }
 }
 
@@ -590,6 +593,9 @@ fn encode_method_map_entry(ecx: @e::EncodeContext,
         do ebml_w.emit_struct_field("origin", 1u) {
             mme.origin.encode(ebml_w);
         }
+        do ebml_w.emit_struct_field("self_mode", 3) {
+            mme.self_mode.encode(ebml_w);
+        }
     }
 }
 
@@ -611,6 +617,10 @@ impl read_method_map_entry_helper for reader::Decoder {
                         Decodable::decode(self);
                     method_origin.tr(xcx)
                 }),
+                self_mode: self.read_field(~"self_mode", 3, || {
+                    let self_mode: ty::SelfMode = Decodable::decode(self);
+                    self_mode
+                }),
             }
         }
     }
@@ -625,7 +635,7 @@ impl read_method_map_entry_helper for reader::Decoder {
                 self_arg: self.read_struct_field("self_arg", 0u, || {
                     self.read_arg(xcx)
                 }),
-                explicit_self: self.read_struct_field("explicit_self", 2u, || {
+                explicit_self: self.read_struct_field("explicit_self", 2, || {
                     let self_type: ast::self_ty_ = Decodable::decode(self);
                     self_type
                 }),
@@ -634,6 +644,10 @@ impl read_method_map_entry_helper for reader::Decoder {
                         Decodable::decode(self);
                     method_origin.tr(xcx)
                 }),
+                self_mode: self.read_struct_field("self_mode", 3, || {
+                    let self_mode: ty::SelfMode = Decodable::decode(self);
+                    self_mode
+                }),
             }
         }
     }
@@ -978,20 +992,6 @@ fn encode_side_tables_for_id(ecx: @e::EncodeContext,
         }
     }
 
-    // I believe it is not necessary to encode this information.  The
-    // ids will appear in the AST but in the *type* information, which
-    // is what we actually use in trans, all modes will have been
-    // resolved.
-    //
-    //for tcx.inferred_modes.find(&id).each |m| {
-    //    ebml_w.tag(c::tag_table_inferred_modes) {||
-    //        ebml_w.id(id);
-    //        ebml_w.tag(c::tag_table_val) {||
-    //            tyencode::enc_mode(ebml_w.writer, ty_str_ctxt(), m);
-    //        }
-    //    }
-    //}
-
     if maps.mutbl_map.contains(&id) {
         do ebml_w.tag(c::tag_table_mutbl) {
             ebml_w.id(id);
diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs
index 92ac90e99da..e40d0e63eb3 100644
--- a/src/librustc/middle/borrowck/gather_loans.rs
+++ b/src/librustc/middle/borrowck/gather_loans.rs
@@ -147,38 +147,6 @@ fn req_loans_in_expr(ex: @ast::expr,
         visit::visit_expr(ex, self, vt);
       }
 
-      ast::expr_call(f, ref args, _) => {
-        let arg_tys = ty::ty_fn_args(ty::expr_ty(self.tcx(), f));
-        let scope_r = ty::re_scope(ex.id);
-        for vec::each2(*args, arg_tys) |arg, arg_ty| {
-            match ty::resolved_mode(self.tcx(), arg_ty.mode) {
-                ast::by_ref => {
-                    let arg_cmt = self.bccx.cat_expr(*arg);
-                    self.guarantee_valid(arg_cmt, m_imm,  scope_r);
-                }
-                ast::by_copy => {}
-            }
-        }
-        visit::visit_expr(ex, self, vt);
-      }
-
-      ast::expr_method_call(_, _, _, ref args, _) => {
-        let arg_tys = ty::ty_fn_args(ty::node_id_to_type(self.tcx(),
-                                                         ex.callee_id));
-        let scope_r = ty::re_scope(ex.id);
-        for vec::each2(*args, arg_tys) |arg, arg_ty| {
-            match ty::resolved_mode(self.tcx(), arg_ty.mode) {
-                ast::by_ref => {
-                    let arg_cmt = self.bccx.cat_expr(*arg);
-                    self.guarantee_valid(arg_cmt, m_imm,  scope_r);
-                }
-                ast::by_copy => {}
-            }
-        }
-
-        visit::visit_expr(ex, self, vt);
-      }
-
       ast::expr_match(ex_v, ref arms) => {
         let cmt = self.bccx.cat_expr(ex_v);
         for (*arms).each |arm| {
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index cd26708ef9a..faf4b1c3106 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -19,7 +19,6 @@ use std::smallintmap::SmallIntMap;
 use syntax::attr;
 use syntax::codemap::span;
 use syntax::codemap;
-use syntax::print::pprust::mode_to_str;
 use syntax::{ast, visit};
 
 /**
@@ -53,7 +52,6 @@ pub enum lint {
     unrecognized_lint,
     non_implicitly_copyable_typarams,
     vecs_implicitly_copyable,
-    deprecated_mode,
     deprecated_pattern,
     non_camel_case_types,
     type_limits,
@@ -61,14 +59,11 @@ pub enum lint {
     deprecated_mutable_fields,
     deprecated_drop,
     unused_unsafe,
-    foreign_mode,
 
     managed_heap_memory,
     owned_heap_memory,
     heap_memory,
 
-    legacy_modes,
-
     unused_variable,
     dead_assignment,
     unused_mut,
@@ -159,20 +154,6 @@ pub fn get_lint_dict() -> LintDict {
             default: warn
          }),
 
-        (~"deprecated_mode",
-         LintSpec {
-            lint: deprecated_mode,
-            desc: "warn about deprecated uses of modes",
-            default: warn
-         }),
-
-        (~"foreign_mode",
-         LintSpec {
-            lint: foreign_mode,
-            desc: "warn about deprecated uses of modes in foreign fns",
-            default: warn
-         }),
-
         (~"deprecated_pattern",
          LintSpec {
             lint: deprecated_pattern,
@@ -208,13 +189,6 @@ pub fn get_lint_dict() -> LintDict {
             default: allow
          }),
 
-        (~"legacy modes",
-         LintSpec {
-            lint: legacy_modes,
-            desc: "allow legacy modes",
-            default: forbid
-         }),
-
         (~"type_limits",
          LintSpec {
             lint: type_limits,
@@ -486,7 +460,6 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
     check_item_path_statement(cx, i);
     check_item_non_camel_case_types(cx, i);
     check_item_heap(cx, i);
-    check_item_deprecated_modes(cx, i);
     check_item_type_limits(cx, i);
     check_item_default_methods(cx, i);
     check_item_deprecated_mutable_fields(cx, i);
@@ -719,20 +692,6 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
 
     fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
                         decl: &ast::fn_decl) {
-        // warn about `&&` mode on foreign functions, both because it is
-        // deprecated and because its semantics have changed recently:
-        for decl.inputs.eachi |i, arg| {
-            match ty::resolved_mode(cx, arg.mode) {
-                ast::by_copy => {}
-                ast::by_ref => {
-                    cx.sess.span_lint(
-                        foreign_mode, fn_id, fn_id, arg.ty.span,
-                        fmt!("foreign function uses `&&` mode \
-                              on argument %u", i));
-                }
-            }
-        }
-
         let tys = vec::map(decl.inputs, |a| a.ty );
         for vec::each(vec::append_one(tys, decl.output)) |ty| {
             match ty.node {
@@ -995,119 +954,13 @@ fn check_item_unused_mut(tcx: ty::ctxt, it: @ast::item) {
     visit::visit_item(it, (), visit);
 }
 
-fn check_fn(tcx: ty::ctxt, fk: &visit::fn_kind, decl: &ast::fn_decl,
-            _body: &ast::blk, span: span, id: ast::node_id) {
+fn check_fn(_: ty::ctxt,
+            fk: &visit::fn_kind,
+            _: &ast::fn_decl,
+            _: &ast::blk,
+            _: span,
+            id: ast::node_id) {
     debug!("lint check_fn fk=%? id=%?", fk, id);
-
-    // Check for deprecated modes
-    match *fk {
-        // don't complain about blocks, since they tend to get their modes
-        // specified from the outside
-        visit::fk_fn_block(*) => {}
-
-        _ => {
-            let fn_ty = ty::node_id_to_type(tcx, id);
-            check_fn_deprecated_modes(tcx, fn_ty, decl, span, id);
-        }
-    }
-
-}
-
-fn check_fn_deprecated_modes(tcx: ty::ctxt, fn_ty: ty::t, decl: &ast::fn_decl,
-                             span: span, id: ast::node_id) {
-    match ty::get(fn_ty).sty {
-        ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) |
-        ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) => {
-            let mut counter = 0;
-            for vec::each2(sig.inputs, decl.inputs) |arg_ty, arg_ast| {
-                counter += 1;
-                debug!("arg %d, ty=%s, mode=%s",
-                       counter,
-                       ty_to_str(tcx, arg_ty.ty),
-                       mode_to_str(arg_ast.mode));
-                match arg_ast.mode {
-                    ast::expl(ast::by_copy) => {
-                        if !tcx.legacy_modes {
-                            tcx.sess.span_lint(
-                                deprecated_mode, id, id, span,
-                                fmt!("argument %d uses by-copy mode",
-                                     counter));
-                        }
-                    }
-
-                    ast::expl(_) => {
-                        tcx.sess.span_lint(
-                            deprecated_mode, id, id,
-                            span,
-                         fmt!("argument %d uses an explicit mode", counter));
-                    }
-
-                    ast::infer(_) => {
-                        if tcx.legacy_modes {
-                            let kind = ty::type_contents(tcx, arg_ty.ty);
-                            if !kind.is_safe_for_default_mode(tcx) {
-                                tcx.sess.span_lint(
-                                    deprecated_mode, id, id,
-                                    span,
-                                    fmt!("argument %d uses the default mode \
-                                          but shouldn't",
-                                         counter));
-                            }
-                        }
-                    }
-                }
-
-                match ty::get(arg_ty.ty).sty {
-                    ty::ty_closure(*) | ty::ty_bare_fn(*) => {
-                        let span = arg_ast.ty.span;
-                        // Recurse to check fn-type argument
-                        match arg_ast.ty.node {
-                            ast::ty_closure(@ast::TyClosure{decl: ref d, _}) |
-                            ast::ty_bare_fn(@ast::TyBareFn{decl: ref d, _})=>{
-                                check_fn_deprecated_modes(tcx, arg_ty.ty,
-                                                          d, span, id);
-                            }
-                            ast::ty_path(*) => {
-                                // This is probably a typedef, so we can't
-                                // see the actual fn decl
-                                // e.g. fn foo(f: InitOp<T>)
-                            }
-                            _ => {
-                                tcx.sess.span_warn(span, ~"what");
-                                error!("arg %d, ty=%s, mode=%s",
-                                       counter,
-                                       ty_to_str(tcx, arg_ty.ty),
-                                       mode_to_str(arg_ast.mode));
-                                error!("%?",arg_ast.ty.node);
-                                fail!()
-                            }
-                        };
-                    }
-                    _ => ()
-                }
-            }
-        }
-
-        _ => tcx.sess.impossible_case(span, ~"check_fn: function has \
-                                              non-fn type")
-    }
-}
-
-fn check_item_deprecated_modes(tcx: ty::ctxt, it: @ast::item) {
-    match it.node {
-        ast::item_ty(ty, _) => {
-            match ty.node {
-                ast::ty_closure(@ast::TyClosure {decl: ref decl, _}) |
-                ast::ty_bare_fn(@ast::TyBareFn {decl: ref decl, _}) => {
-                    let fn_ty = ty::node_id_to_type(tcx, it.id);
-                    check_fn_deprecated_modes(
-                        tcx, fn_ty, decl, ty.span, it.id)
-                }
-                _ => ()
-            }
-        }
-        _ => ()
-    }
 }
 
 pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index fa491705df1..94d82d0acb8 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -236,19 +236,19 @@ struct LocalInfo {
 }
 
 enum VarKind {
-    Arg(node_id, ident, rmode),
+    Arg(node_id, ident),
     Local(LocalInfo),
     ImplicitRet
 }
 
 fn relevant_def(def: def) -> Option<node_id> {
     match def {
-      def_binding(nid, _) |
-      def_arg(nid, _, _) |
-      def_local(nid, _) |
-      def_self(nid, _) => Some(nid),
+        def_binding(nid, _) |
+        def_arg(nid, _) |
+        def_local(nid, _) |
+        def_self(nid, _) => Some(nid),
 
-      _ => None
+        _ => None
     }
 }
 
@@ -321,10 +321,9 @@ pub impl IrMaps {
         self.num_vars += 1;
 
         match vk {
-            Local(LocalInfo {id:node_id, _}) |
-            Arg(node_id, _, _) => {
+            Local(LocalInfo { id: node_id, _ }) | Arg(node_id, _) => {
                 self.variable_map.insert(node_id, v);
-            }
+            },
             ImplicitRet => {}
         }
 
@@ -345,8 +344,9 @@ pub impl IrMaps {
 
     fn variable_name(&mut self, var: Variable) -> @~str {
         match self.var_kinds[*var] {
-            Local(LocalInfo {ident: nm, _}) |
-            Arg(_, nm, _) => self.tcx.sess.str_of(nm),
+            Local(LocalInfo { ident: nm, _ }) | Arg(_, nm) => {
+                self.tcx.sess.str_of(nm)
+            },
             ImplicitRet => @~"<implicit-ret>"
         }
     }
@@ -372,25 +372,22 @@ pub impl IrMaps {
         let vk = self.var_kinds[*var];
         debug!("Node %d is a last use of variable %?", expr_id, vk);
         match vk {
-          Arg(id, _, by_copy) |
-          Local(LocalInfo {id: id, kind: FromLetNoInitializer, _}) |
-          Local(LocalInfo {id: id, kind: FromLetWithInitializer, _}) |
-          Local(LocalInfo {id: id, kind: FromMatch(_), _}) => {
-            let v = match self.last_use_map.find(&expr_id) {
-              Some(&v) => v,
-              None => {
-                let v = @mut ~[];
-                self.last_use_map.insert(expr_id, v);
-                v
-              }
-            };
+            Arg(id, _) |
+            Local(LocalInfo { id: id, kind: FromLetNoInitializer, _ }) |
+            Local(LocalInfo { id: id, kind: FromLetWithInitializer, _ }) |
+            Local(LocalInfo { id: id, kind: FromMatch(_), _ }) => {
+                let v = match self.last_use_map.find(&expr_id) {
+                    Some(&v) => v,
+                    None => {
+                        let v = @mut ~[];
+                        self.last_use_map.insert(expr_id, v);
+                        v
+                    }
+                };
 
-            v.push(id);
-          }
-          Arg(_, _, by_ref) |
-          ImplicitRet => {
-            debug!("--but it is not owned");
-          }
+                v.push(id);
+            }
+            ImplicitRet => debug!("--but it is not owned"),
         }
     }
 }
@@ -424,12 +421,11 @@ fn visit_fn(fk: &visit::fn_kind,
     }
 
     for decl.inputs.each |arg| {
-        let mode = ty::resolved_mode(self.tcx, arg.mode);
         do pat_util::pat_bindings(self.tcx.def_map, arg.pat)
                 |_bm, arg_id, _x, path| {
             debug!("adding argument %d", arg_id);
             let ident = ast_util::path_to_ident(path);
-            fn_maps.add_variable(Arg(arg_id, ident, mode));
+            fn_maps.add_variable(Arg(arg_id, ident));
         }
     };
 
@@ -439,16 +435,13 @@ fn visit_fn(fk: &visit::fn_kind,
             match method.self_ty.node {
                 sty_value | sty_region(*) | sty_box(_) | sty_uniq(_) => {
                     fn_maps.add_variable(Arg(method.self_id,
-                                             special_idents::self_,
-                                             by_copy));
+                                             special_idents::self_));
                 }
                 sty_static => {}
             }
         }
         fk_dtor(_, _, self_id, _) => {
-            fn_maps.add_variable(Arg(self_id,
-                                     special_idents::self_,
-                                     by_copy));
+            fn_maps.add_variable(Arg(self_id, special_idents::self_));
         }
         fk_item_fn(*) | fk_anon(*) | fk_fn_block(*) => {}
     }
@@ -973,30 +966,8 @@ pub impl Liveness {
         entry_ln
     }
 
-    fn propagate_through_fn_block(&self, decl: &fn_decl, blk: &blk)
-                                 -> LiveNode {
-        // inputs passed by & mode should be considered live on exit:
-        for decl.inputs.each |arg| {
-            match ty::resolved_mode(self.tcx, arg.mode) {
-                by_ref => {
-                    // By val and by ref do not own, so register a
-                    // read at the end.  This will prevent us from
-                    // moving out of such variables but also prevent
-                    // us from registering last uses and so forth.
-                    do pat_util::pat_bindings(self.tcx.def_map, arg.pat)
-                        |_bm, arg_id, _sp, _path|
-                    {
-                        let var = self.variable(arg_id, blk.span);
-                        self.acc(self.s.exit_ln, var, ACC_READ);
-                    }
-                }
-                by_copy => {
-                    // By copy is an owned mode.  If we don't use the
-                    // variable, nobody will.
-                }
-            }
-        }
-
+    fn propagate_through_fn_block(&self, _: &fn_decl, blk: &blk)
+                                  -> LiveNode {
         // the fallthrough exit is only for those cases where we do not
         // explicitly return:
         self.init_from_succ(self.s.fallthrough_ln, self.s.exit_ln);
@@ -1771,7 +1742,7 @@ pub impl Liveness {
             // borrow checker
             let vk = self.ir.var_kinds[*var];
             match vk {
-              Arg(_, name, _) => {
+              Arg(_, name) => {
                 self.tcx.sess.span_err(
                     move_expr.span,
                     fmt!("illegal move from argument `%s`, which is not \
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 49c5717a357..31cb39bc231 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -482,17 +482,14 @@ pub impl mem_categorization_ctxt {
             }
           }
 
-          ast::def_arg(vid, mode, mutbl) => {
+          ast::def_arg(vid, mutbl) => {
             // Idea: make this could be rewritten to model by-ref
             // stuff as `&const` and `&mut`?
 
             // m: mutability of the argument
             // lp: loan path, must be none for aliasable things
             let m = if mutbl {McDeclared} else {McImmutable};
-            let lp = match ty::resolved_mode(self.tcx, mode) {
-                ast::by_copy => Some(@lp_arg(vid)),
-                ast::by_ref => None,
-            };
+            let lp = Some(@lp_arg(vid));
             @cmt_ {
                 id:id,
                 span:span,
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index 0eb5c53d688..fe1466bf808 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -718,41 +718,22 @@ pub impl VisitContext {
                     receiver_expr: @expr,
                     visitor: vt<VisitContext>)
     {
-        self.use_fn_arg(by_copy, receiver_expr, visitor);
+        self.use_fn_arg(receiver_expr, visitor);
     }
 
     fn use_fn_args(&self,
-                   callee_id: node_id,
+                   _: node_id,
                    arg_exprs: &[@expr],
-                   visitor: vt<VisitContext>)
-    {
-        /*!
-         *
-         * Uses the argument expressions according to the function modes.
-         */
-
-        let arg_tys =
-            ty::ty_fn_args(ty::node_id_to_type(self.tcx, callee_id));
-        for vec::each2(arg_exprs, arg_tys) |arg_expr, arg_ty| {
-            let arg_mode = ty::resolved_mode(self.tcx, arg_ty.mode);
-            self.use_fn_arg(arg_mode, *arg_expr, visitor);
+                   visitor: vt<VisitContext>) {
+        //! Uses the argument expressions.
+        for arg_exprs.each |arg_expr| {
+            self.use_fn_arg(*arg_expr, visitor);
         }
     }
 
-    fn use_fn_arg(&self,
-                  arg_mode: rmode,
-                  arg_expr: @expr,
-                  visitor: vt<VisitContext>)
-    {
-        /*!
-         *
-         * Uses the argument according to the given argument mode.
-         */
-
-        match arg_mode {
-            by_ref => self.use_expr(arg_expr, Read, visitor),
-            by_copy => self.consume_expr(arg_expr, visitor)
-        }
+    fn use_fn_arg(&self, arg_expr: @expr, visitor: vt<VisitContext>) {
+        //! Uses the argument.
+        self.consume_expr(arg_expr, visitor)
     }
 
     fn arms_have_by_move_bindings(&self,
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 5354ffc5d3c..681c3863327 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -42,7 +42,7 @@ use syntax::ast::Generics;
 use syntax::ast::{gt, ident, inherited, item, item_struct};
 use syntax::ast::{item_const, item_enum, item_fn, item_foreign_mod};
 use syntax::ast::{item_impl, item_mac, item_mod, item_trait, item_ty, le};
-use syntax::ast::{local, local_crate, lt, method, mode, mul};
+use syntax::ast::{local, local_crate, lt, method, mul};
 use syntax::ast::{named_field, ne, neg, node_id, pat, pat_enum, pat_ident};
 use syntax::ast::{Path, pat_lit, pat_range, pat_struct};
 use syntax::ast::{prim_ty, private, provided};
@@ -123,7 +123,7 @@ pub struct Export2 {
 pub enum PatternBindingMode {
     RefutableMode,
     LocalIrrefutableMode,
-    ArgumentIrrefutableMode(mode)
+    ArgumentIrrefutableMode,
 }
 
 #[deriving(Eq)]
@@ -3708,8 +3708,7 @@ pub impl Resolver {
                 }
                 Some(declaration) => {
                     for declaration.inputs.each |argument| {
-                        let binding_mode =
-                            ArgumentIrrefutableMode(argument.mode);
+                        let binding_mode = ArgumentIrrefutableMode;
                         let mutability =
                             if argument.is_mutbl {Mutable} else {Immutable};
                         self.resolve_pattern(argument.pat,
@@ -4184,10 +4183,9 @@ pub impl Resolver {
                                     // But for locals, we use `def_local`.
                                     def_local(pattern.id, is_mutable)
                                 }
-                                ArgumentIrrefutableMode(argument_mode) => {
+                                ArgumentIrrefutableMode => {
                                     // And for function arguments, `def_arg`.
-                                    def_arg(pattern.id, argument_mode,
-                                            is_mutable)
+                                    def_arg(pattern.id, is_mutable)
                                 }
                             };
 
diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs
index 3d1c0f3f82c..9c84b2a4182 100644
--- a/src/librustc/middle/trans/asm.rs
+++ b/src/librustc/middle/trans/asm.rs
@@ -33,11 +33,16 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
         constraints.push(copy *c);
 
         let aoutty = ty::arg {
-            mode: ast::expl(ast::by_copy),
             ty: expr_ty(bcx, out)
         };
         aoutputs.push(unpack_result!(bcx, {
-            callee::trans_arg_expr(bcx, aoutty, out, &mut cleanups, None, callee::DontAutorefArg)
+            callee::trans_arg_expr(bcx,
+                                   aoutty,
+                                   ty::ByCopy,
+                                   out,
+                                   &mut cleanups,
+                                   None,
+                                   callee::DontAutorefArg)
         }));
 
         let e = match out.node {
@@ -46,12 +51,17 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
         };
 
         let outty = ty::arg {
-            mode: ast::expl(ast::by_copy),
             ty: expr_ty(bcx, e)
         };
 
         unpack_result!(bcx, {
-            callee::trans_arg_expr(bcx, outty, e, &mut cleanups, None, callee::DontAutorefArg)
+            callee::trans_arg_expr(bcx,
+                                   outty,
+                                   ty::ByCopy,
+                                   e,
+                                   &mut cleanups,
+                                   None,
+                                   callee::DontAutorefArg)
         })
 
     };
@@ -66,12 +76,17 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
         constraints.push(copy *c);
 
         let inty = ty::arg {
-            mode: ast::expl(ast::by_copy),
             ty: expr_ty(bcx, in)
         };
 
         unpack_result!(bcx, {
-            callee::trans_arg_expr(bcx, inty, in, &mut cleanups, None, callee::DontAutorefArg)
+            callee::trans_arg_expr(bcx,
+                                   inty,
+                                   ty::ByCopy,
+                                   in,
+                                   &mut cleanups,
+                                   None,
+                                   callee::DontAutorefArg)
         })
 
     };
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 03a85201862..efa10dfc2aa 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1728,7 +1728,6 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
                             raw_llargs: &[ValueRef],
                             arg_tys: &[ty::arg]) -> block {
     let _icx = fcx.insn_ctxt("copy_args_to_allocas");
-    let tcx = bcx.tcx();
     let mut bcx = bcx;
 
     match fcx.llself {
@@ -1757,24 +1756,16 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
         // the argument would be passed by value, we store it into an alloca.
         // This alloca should be optimized away by LLVM's mem-to-reg pass in
         // the event it's not truly needed.
-        let llarg;
-        match ty::resolved_mode(tcx, arg_ty.mode) {
-            ast::by_ref => {
-                llarg = raw_llarg;
-            }
-            ast::by_copy => {
-                // only by value if immediate:
-                if datum::appropriate_mode(arg_ty.ty).is_by_value() {
-                    let alloc = alloc_ty(bcx, arg_ty.ty);
-                    Store(bcx, raw_llarg, alloc);
-                    llarg = alloc;
-                } else {
-                    llarg = raw_llarg;
-                }
+        // only by value if immediate:
+        let llarg = if datum::appropriate_mode(arg_ty.ty).is_by_value() {
+            let alloc = alloc_ty(bcx, arg_ty.ty);
+            Store(bcx, raw_llarg, alloc);
+            alloc
+        } else {
+            raw_llarg
+        };
 
-                add_clean(bcx, llarg, arg_ty.ty);
-            }
-        }
+        add_clean(bcx, llarg, arg_ty.ty);
 
         bcx = _match::bind_irrefutable_pat(bcx,
                                           args[arg_n].pat,
@@ -1966,7 +1957,6 @@ pub fn trans_enum_variant(ccx: @CrateContext,
     // Translate variant arguments to function arguments.
     let fn_args = do args.map |varg| {
         ast::arg {
-            mode: ast::expl(ast::by_copy),
             is_mutbl: false,
             ty: varg.ty,
             pat: ast_util::ident_to_pat(
@@ -2041,7 +2031,6 @@ pub fn trans_tuple_struct(ccx: @CrateContext,
     // Translate struct fields to function arguments.
     let fn_args = do fields.map |field| {
         ast::arg {
-            mode: ast::expl(ast::by_copy),
             is_mutbl: false,
             ty: field.node.ty,
             pat: ast_util::ident_to_pat(ccx.tcx.sess.next_node_id(),
@@ -2408,8 +2397,8 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
             } else {
                 let start_fn_type = csearch::get_type(ccx.tcx,
                                                       start_def_id).ty;
-                trans_external_path(ccx, start_def_id, start_fn_type)
-            };
+                trans_external_path(ccx, start_def_id, start_fn_type);
+            }
 
             let retptr = llvm::LLVMBuildAlloca(bld, T_i8(), noname());
 
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 19658555861..ad0fea3b4b4 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -57,7 +57,7 @@ pub struct MethodData {
     llfn: ValueRef,
     llself: ValueRef,
     self_ty: ty::t,
-    self_mode: ast::rmode
+    self_mode: ty::SelfMode,
 }
 
 pub enum CalleeData {
@@ -378,10 +378,20 @@ pub fn trans_lang_call(bcx: block,
         csearch::get_type(bcx.ccx().tcx, did).ty
     };
     let rty = ty::ty_fn_ret(fty);
-    return callee::trans_call_inner(
-        bcx, None, fty, rty,
-        |bcx| trans_fn_ref_with_vtables_to_callee(bcx, did, 0, ~[], None),
-        ArgVals(args), dest, DontAutorefArg);
+    callee::trans_call_inner(bcx,
+                             None,
+                             fty,
+                             rty,
+                             |bcx| {
+                                trans_fn_ref_with_vtables_to_callee(bcx,
+                                                                    did,
+                                                                    0,
+                                                                    ~[],
+                                                                    None)
+                             },
+                             ArgVals(args),
+                             dest,
+                             DontAutorefArg)
 }
 
 pub fn trans_lang_call_with_type_params(bcx: block,
@@ -483,7 +493,8 @@ pub fn trans_call_inner(in_cx: block,
                 }
                 Method(d) => {
                     // Weird but true: we pass self in the *environment* slot!
-                    let llself = PointerCast(bcx, d.llself,
+                    let llself = PointerCast(bcx,
+                                             d.llself,
                                              T_opaque_box_ptr(ccx));
                     (d.llfn, llself)
                 }
@@ -520,7 +531,7 @@ pub fn trans_call_inner(in_cx: block,
         // Now that the arguments have finished evaluating, we need to revoke
         // the cleanup for the self argument, if it exists
         match callee.data {
-            Method(d) if d.self_mode == ast::by_copy => {
+            Method(d) if d.self_mode == ty::ByCopy => {
                 revoke_clean(bcx, d.llself);
             }
             _ => {}
@@ -629,7 +640,11 @@ pub fn trans_args(cx: block,
         let last = arg_exprs.len() - 1u;
         for vec::eachi(arg_exprs) |i, arg_expr| {
             let arg_val = unpack_result!(bcx, {
-                trans_arg_expr(bcx, arg_tys[i], *arg_expr, &mut temp_cleanups,
+                trans_arg_expr(bcx,
+                               arg_tys[i],
+                               ty::ByCopy,
+                               *arg_expr,
+                               &mut temp_cleanups,
                                if i == last { ret_flag } else { None },
                                autoref_arg)
             });
@@ -660,6 +675,7 @@ pub enum AutorefArg {
 // call takes place:
 pub fn trans_arg_expr(bcx: block,
                       formal_ty: ty::arg,
+                      self_mode: ty::SelfMode,
                       arg_expr: @ast::expr,
                       temp_cleanups: &mut ~[ValueRef],
                       ret_flag: Option<ValueRef>,
@@ -667,10 +683,10 @@ pub fn trans_arg_expr(bcx: block,
     let _icx = bcx.insn_ctxt("trans_arg_expr");
     let ccx = bcx.ccx();
 
-    debug!("trans_arg_expr(formal_ty=(%?,%s), arg_expr=%s, \
+    debug!("trans_arg_expr(formal_ty=(%s), self_mode=%?, arg_expr=%s, \
             ret_flag=%?)",
-           formal_ty.mode,
            formal_ty.ty.repr(bcx.tcx()),
+           self_mode,
            arg_expr.repr(bcx.tcx()),
            ret_flag.map(|v| bcx.val_str(*v)));
     let _indenter = indenter();
@@ -686,8 +702,7 @@ pub fn trans_arg_expr(bcx: block,
                     blk @ @ast::expr {
                         node: ast::expr_fn_block(ref decl, ref body),
                         _
-                    }) =>
-                {
+                    }) => {
                     let scratch_ty = expr_ty(bcx, arg_expr);
                     let scratch = alloc_ty(bcx, scratch_ty);
                     let arg_ty = expr_ty(bcx, arg_expr);
@@ -714,8 +729,6 @@ pub fn trans_arg_expr(bcx: block,
 
     debug!("   arg datum: %s", arg_datum.to_str(bcx.ccx()));
 
-    // finally, deal with the various modes
-    let arg_mode = ty::resolved_mode(ccx.tcx, formal_ty.mode);
     let mut val;
     if ty::type_is_bot(arg_datum.ty) {
         // For values of type _|_, we generate an
@@ -735,24 +748,27 @@ pub fn trans_arg_expr(bcx: block,
                 val = arg_datum.to_ref_llval(bcx);
             }
             DontAutorefArg => {
-                match arg_mode {
-                    ast::by_ref => {
+                match self_mode {
+                    ty::ByRef => {
                         // This assertion should really be valid, but because
                         // the explicit self code currently passes by-ref, it
                         // does not hold.
                         //
                         //assert !bcx.ccx().maps.moves_map.contains_key(
                         //    &arg_expr.id);
+                        debug!("by ref arg with type %s",
+                               bcx.ty_to_str(arg_datum.ty));
                         val = arg_datum.to_ref_llval(bcx);
                     }
-
-                    ast::by_copy => {
+                    ty::ByCopy => {
                         debug!("by copy arg with type %s, storing to scratch",
                                bcx.ty_to_str(arg_datum.ty));
                         let scratch = scratch_datum(bcx, arg_datum.ty, false);
 
-                        arg_datum.store_to_datum(bcx, arg_expr.id,
-                                                 INIT, scratch);
+                        arg_datum.store_to_datum(bcx,
+                                                 arg_expr.id,
+                                                 INIT,
+                                                 scratch);
 
                         // Technically, ownership of val passes to the callee.
                         // However, we must cleanup should we fail before the
@@ -761,12 +777,8 @@ pub fn trans_arg_expr(bcx: block,
                         temp_cleanups.push(scratch.val);
 
                         match arg_datum.appropriate_mode() {
-                            ByValue => {
-                                val = Load(bcx, scratch.val);
-                            }
-                            ByRef => {
-                                val = scratch.val;
-                            }
+                            ByValue => val = Load(bcx, scratch.val),
+                            ByRef => val = scratch.val,
                         }
                     }
                 }
@@ -776,6 +788,10 @@ pub fn trans_arg_expr(bcx: block,
         if formal_ty.ty != arg_datum.ty {
             // this could happen due to e.g. subtyping
             let llformal_ty = type_of::type_of_explicit_arg(ccx, &formal_ty);
+            let llformal_ty = match self_mode {
+                ty::ByRef => T_ptr(llformal_ty),
+                ty::ByCopy => llformal_ty,
+            };
             debug!("casting actual type (%s) to match formal (%s)",
                    bcx.val_str(val), bcx.llty_str(llformal_ty));
             val = PointerCast(bcx, val, llformal_ty);
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index f666eb2aaa6..f83562add31 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -1072,7 +1072,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum {
                 }
             }
         }
-        ast::def_arg(nid, _, _) => {
+        ast::def_arg(nid, _) => {
             take_local(bcx, bcx.fcx.llargs, nid)
         }
         ast::def_local(nid, _) | ast::def_binding(nid, _) => {
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 66ed71072bf..587f13ad65e 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -791,10 +791,11 @@ pub fn trans_intrinsic(ccx: @CrateContext,
                 sigil: ast::BorrowedSigil,
                 onceness: ast::Many,
                 region: ty::re_bound(ty::br_anon(0)),
-                sig: FnSig {bound_lifetime_names: opt_vec::Empty,
-                            inputs: ~[arg {mode: ast::expl(ast::by_copy),
-                                           ty: star_u8}],
-                            output: ty::mk_nil()}
+                sig: FnSig {
+                    bound_lifetime_names: opt_vec::Empty,
+                    inputs: ~[ arg { ty: star_u8 } ],
+                    output: ty::mk_nil()
+                }
             });
             let datum = Datum {val: get_param(decl, first_real_arg),
                                mode: ByRef, ty: fty, source: ZeroMem};
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 44e9c0f6802..90f9f93be2b 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -145,14 +145,18 @@ pub fn trans_self_arg(bcx: block,
     let _icx = bcx.insn_ctxt("impl::trans_self_arg");
     let mut temp_cleanups = ~[];
 
-    // Compute the mode and type of self.
+    // Compute the type of self.
     let self_arg = arg {
-        mode: mentry.self_arg.mode,
         ty: monomorphize_type(bcx, mentry.self_arg.ty)
     };
 
-    let result = trans_arg_expr(bcx, self_arg, base,
-                                &mut temp_cleanups, None, DontAutorefArg);
+    let result = trans_arg_expr(bcx,
+                                self_arg,
+                                mentry.self_mode,
+                                base,
+                                &mut temp_cleanups,
+                                None,
+                                DontAutorefArg);
 
     // FIXME(#3446)---this is wrong, actually.  The temp_cleanups
     // should be revoked only after all arguments have been passed.
@@ -224,14 +228,13 @@ pub fn trans_method_callee(bcx: block,
         typeck::method_static(did) => {
             let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
             let Result {bcx, val} = trans_self_arg(bcx, self, mentry);
-            let tcx = bcx.tcx();
             Callee {
                 bcx: bcx,
                 data: Method(MethodData {
                     llfn: callee_fn.llfn,
                     llself: val,
                     self_ty: node_id_type(bcx, self.id),
-                    self_mode: ty::resolved_mode(tcx, mentry.self_arg.mode)
+                    self_mode: mentry.self_mode,
                 })
             }
         }
@@ -442,7 +445,7 @@ pub fn trans_monomorphized_callee(bcx: block,
                                   trait_id: ast::def_id,
                                   n_method: uint,
                                   vtbl: typeck::vtable_origin)
-                               -> Callee {
+                                  -> Callee {
     let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee");
     return match vtbl {
       typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
@@ -463,8 +466,11 @@ pub fn trans_monomorphized_callee(bcx: block,
               bcx, mth_id, impl_did, callee_id, rcvr_origins);
 
           // translate the function
-          let callee = trans_fn_ref_with_vtables(
-              bcx, mth_id, callee_id, callee_substs, Some(callee_origins));
+          let callee = trans_fn_ref_with_vtables(bcx,
+                                                 mth_id,
+                                                 callee_id,
+                                                 callee_substs,
+                                                 Some(callee_origins));
 
           // create a llvalue that represents the fn ptr
           let fn_ty = node_id_type(bcx, callee_id);
@@ -472,14 +478,13 @@ pub fn trans_monomorphized_callee(bcx: block,
           let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty);
 
           // combine the self environment with the rest
-          let tcx = bcx.tcx();
           Callee {
               bcx: bcx,
               data: Method(MethodData {
                   llfn: llfn_val,
                   llself: llself_val,
                   self_ty: node_id_type(bcx, base.id),
-                  self_mode: ty::resolved_mode(tcx, mentry.self_arg.mode)
+                  self_mode: mentry.self_mode,
               })
           }
       }
@@ -496,7 +501,7 @@ pub fn combine_impl_and_methods_tps(bcx: block,
                                     impl_did: ast::def_id,
                                     callee_id: ast::node_id,
                                     rcvr_substs: &[ty::t])
-                                 -> ~[ty::t] {
+                                    -> ~[ty::t] {
     /*!
     *
     * Creates a concatenated set of substitutions which includes
@@ -668,7 +673,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
             Store(bcx, llself, llscratch);
             llself = llscratch;
 
-            self_mode = ast::by_ref;
+            self_mode = ty::ByRef;
         }
         ast::sty_box(_) => {
             // Bump the reference count on the box.
@@ -686,7 +691,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
             Store(bcx, llself, llscratch);
             llself = llscratch;
 
-            self_mode = ast::by_ref;
+            self_mode = ty::ByRef;
         }
         ast::sty_uniq(_) => {
             // Pass the unique pointer.
@@ -699,7 +704,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
             Store(bcx, llself, llscratch);
             llself = llscratch;
 
-            self_mode = ast::by_ref;
+            self_mode = ty::ByRef;
         }
     }
 
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 741b111b6a0..7e59f580a2c 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -280,9 +280,15 @@ pub impl Reflector {
 
             let make_get_disr = || {
                 let sub_path = bcx.fcx.path + ~[path_name(special_idents::anon)];
-                let sym = mangle_internal_name_by_path_and_seq(ccx, sub_path, ~"get_disr");
-                let args = [ty::arg { mode: ast::expl(ast::by_copy),
-                                      ty: opaqueptrty }];
+                let sym = mangle_internal_name_by_path_and_seq(ccx,
+                                                               sub_path,
+                                                               ~"get_disr");
+                let args = [
+                    ty::arg {
+                        ty: opaqueptrty
+                    }
+                ];
+
                 let llfty = type_of_fn(ccx, args, ty::mk_int());
                 let llfdecl = decl_internal_cdecl_fn(ccx.llmod, sym, llfty);
                 let arg = unsafe {
@@ -347,13 +353,7 @@ pub impl Reflector {
 
     fn visit_sig(&mut self, retval: uint, sig: &ty::FnSig) {
         for sig.inputs.eachi |i, arg| {
-            let modeval = match arg.mode {
-                ast::infer(_) => 0u,
-                ast::expl(e) => match e {
-                    ast::by_ref => 1u,
-                    ast::by_copy => 5u
-                }
-            };
+            let modeval = 5u;   // "by copy"
             let extra = ~[self.c_uint(i),
                          self.c_uint(modeval),
                          self.c_tydesc(arg.ty)];
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 5bf01b9a883..a842f91f0ed 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -19,11 +19,8 @@ use util::ppaux;
 
 use syntax::ast;
 
-pub fn arg_is_indirect(ccx: @CrateContext, arg: &ty::arg) -> bool {
-    match ty::resolved_mode(ccx.tcx, arg.mode) {
-        ast::by_copy => !ty::type_is_immediate(arg.ty),
-        ast::by_ref => true
-    }
+pub fn arg_is_indirect(_: @CrateContext, arg: &ty::arg) -> bool {
+    !ty::type_is_immediate(arg.ty)
 }
 
 pub fn type_of_explicit_arg(ccx: @CrateContext, arg: &ty::arg) -> TypeRef {
diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs
index 3ec467921c6..33145dd4334 100644
--- a/src/librustc/middle/trans/type_use.rs
+++ b/src/librustc/middle/trans/type_use.rs
@@ -78,12 +78,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
         ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) |
         ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => {
             for vec::each(sig.inputs) |arg| {
-                match ty::resolved_mode(ccx.tcx, arg.mode) {
-                    by_copy => {
-                        type_needs(cx, use_repr, arg.ty);
-                    }
-                    by_ref => {}
-                }
+                type_needs(cx, use_repr, arg.ty);
             }
         }
         _ => ()
@@ -332,15 +327,9 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
         node_type_needs(cx, use_tydesc, val.id);
       }
       expr_call(f, _, _) => {
-          for vec::each(
-              ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx, f.id))
-          ) |a| {
-              match a.mode {
-                  expl(by_copy) => {
-                      type_needs(cx, use_repr, a.ty);
-                  }
-                  _ => ()
-              }
+          for vec::each(ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx,
+                                                           f.id))) |a| {
+              type_needs(cx, use_repr, a.ty);
           }
       }
       expr_method_call(rcvr, _, _, _, _) => {
@@ -349,12 +338,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
 
         for ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx,
                                                e.callee_id)).each |a| {
-          match a.mode {
-              expl(by_copy) => {
-                  type_needs(cx, use_repr, a.ty);
-              }
-              _ => ()
-          }
+            type_needs(cx, use_repr, a.ty);
         }
         mark_for_method_call(cx, e.id, e.callee_id);
       }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 053b03bf6d7..c7fb1e94adf 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -38,7 +38,6 @@ use syntax::ast_util;
 use syntax::attr;
 use syntax::codemap::span;
 use syntax::codemap;
-use syntax::print::pprust;
 use syntax::parse::token::special_idents;
 use syntax::{ast, ast_map};
 use syntax::opt_vec::OptVec;
@@ -48,11 +47,8 @@ use syntax;
 
 // Data types
 
-// Note: after typeck, you should use resolved_mode() to convert this mode
-// into an rmode, which will take into account the results of mode inference.
-#[deriving(Eq)]
+#[deriving(Eq, IterBytes)]
 pub struct arg {
-    mode: ast::mode,
     ty: t
 }
 
@@ -99,6 +95,16 @@ pub enum TraitStore {
     RegionTraitStore(Region),   // &Trait
 }
 
+// XXX: This should probably go away at some point. Maybe after destructors
+// do?
+#[auto_encode]
+#[auto_decode]
+#[deriving(Eq)]
+pub enum SelfMode {
+    ByCopy,
+    ByRef,
+}
+
 pub struct field_ty {
   ident: ident,
   id: def_id,
@@ -270,7 +276,6 @@ struct ctxt_ {
     ast_ty_to_ty_cache: @mut HashMap<node_id, ast_ty_to_ty_cache_entry>,
     enum_var_cache: @mut HashMap<def_id, @~[VariantInfo]>,
     ty_param_defs: @mut HashMap<ast::node_id, TypeParameterDef>,
-    inferred_modes: @mut HashMap<ast::node_id, ast::mode>,
     adjustments: @mut HashMap<ast::node_id, @AutoAdjustment>,
     normalized_cache: @mut HashMap<t, t>,
     lang_items: middle::lang_items::LanguageItems,
@@ -630,7 +635,6 @@ pub enum type_err {
     terr_record_mutability,
     terr_record_fields(expected_found<ident>),
     terr_arg_count,
-    terr_mode_mismatch(expected_found<mode>),
     terr_regions_does_not_outlive(Region, Region),
     terr_regions_not_same(Region, Region),
     terr_regions_no_overlap(Region, Region),
@@ -919,7 +923,6 @@ pub fn mk_ctxt(s: session::Session,
         trait_method_def_ids: @mut HashMap::new(),
         trait_methods_cache: @mut HashMap::new(),
         ty_param_defs: @mut HashMap::new(),
-        inferred_modes: @mut HashMap::new(),
         adjustments: @mut HashMap::new(),
         normalized_cache: new_ty_hash(),
         lang_items: lang_items,
@@ -1199,15 +1202,17 @@ pub fn mk_bare_fn(cx: ctxt, fty: BareFnTy) -> t {
 }
 
 pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t {
-    let input_args = input_tys.map(|t| arg {mode: ast::expl(ast::by_copy),
-                                            ty: *t});
+    let input_args = input_tys.map(|t| arg { ty: *t });
     mk_bare_fn(cx,
                BareFnTy {
                    purity: ast::pure_fn,
                    abis: AbiSet::Rust(),
-                   sig: FnSig {bound_lifetime_names: opt_vec::Empty,
-                               inputs: input_args,
-                               output: output}})
+                   sig: FnSig {
+                    bound_lifetime_names: opt_vec::Empty,
+                    inputs: input_args,
+                    output: output
+                   }
+                })
 }
 
 
@@ -1258,40 +1263,14 @@ pub fn mach_sty(cfg: @session::config, t: t) -> sty {
     }
 }
 
-pub fn default_arg_mode_for_ty(tcx: ctxt, ty: ty::t) -> ast::rmode {
-    return if tcx.legacy_modes {
-        if type_is_borrowed(ty) {
-            // the old mode default was ++ for things like &ptr, but to be
-            // forward-compatible with non-legacy, we should use +
-            ast::by_copy
-        } else if ty::type_is_immediate(ty) {
-            ast::by_copy
-        } else {
-            ast::by_ref
-        }
-    } else {
-        ast::by_copy
-    };
-
-    fn type_is_borrowed(ty: t) -> bool {
-        match ty::get(ty).sty {
-            ty::ty_rptr(*) => true,
-            ty_evec(_, vstore_slice(_)) => true,
-            ty_estr(vstore_slice(_)) => true,
-
-            // technically, we prob ought to include
-            // &fn(), but that is treated specially due to #2202
-            _ => false
-        }
-    }
-}
-
 pub fn walk_ty(ty: t, f: &fn(t)) {
     maybe_walk_ty(ty, |t| { f(t); true });
 }
 
 pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) {
-    if !f(ty) { return; }
+    if !f(ty) {
+        return;
+    }
     match get(ty).sty {
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
       ty_estr(_) | ty_type | ty_opaque_box | ty_self(_) |
@@ -1323,7 +1302,9 @@ pub fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: &fn(t) -> t) -> t {
 
 pub fn fold_sig(sig: &FnSig, fldop: &fn(t) -> t) -> FnSig {
     let args = do sig.inputs.map |arg| {
-        arg { mode: arg.mode, ty: fldop(arg.ty) }
+        arg {
+            ty: fldop(arg.ty)
+        }
     };
 
     FnSig {
@@ -2696,13 +2677,6 @@ impl to_bytes::IterBytes for field {
     }
 }
 
-impl to_bytes::IterBytes for arg {
-    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
-        to_bytes::iter_bytes_2(&self.mode,
-                               &self.ty, lsb0, f)
-    }
-}
-
 impl to_bytes::IterBytes for FnSig {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_2(&self.inputs,
@@ -3368,78 +3342,6 @@ pub fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) {
     }
 }
 
-// Maintains a little union-set tree for inferred modes.  `canon()` returns
-// the current head value for `m0`.
-fn canon<T:Copy + cmp::Eq>(tbl: &mut HashMap<ast::node_id, ast::inferable<T>>,
-                           m0: ast::inferable<T>) -> ast::inferable<T> {
-    match m0 {
-        ast::infer(id) => {
-            let m1 = match tbl.find(&id) {
-                None => return m0,
-                Some(&m1) => m1
-            };
-            let cm1 = canon(tbl, m1);
-            // path compression:
-            if cm1 != m1 { tbl.insert(id, cm1); }
-            cm1
-        },
-        _ => m0
-    }
-}
-
-// Maintains a little union-set tree for inferred modes.  `resolve_mode()`
-// returns the current head value for `m0`.
-pub fn canon_mode(cx: ctxt, m0: ast::mode) -> ast::mode {
-    canon(cx.inferred_modes, m0)
-}
-
-// Returns the head value for mode, failing if `m` was a infer(_) that
-// was never inferred.  This should be safe for use after typeck.
-pub fn resolved_mode(cx: ctxt, m: ast::mode) -> ast::rmode {
-    match canon_mode(cx, m) {
-      ast::infer(_) => {
-        cx.sess.bug(fmt!("mode %? was never resolved", m));
-      }
-      ast::expl(m0) => m0
-    }
-}
-
-pub fn arg_mode(cx: ctxt, a: arg) -> ast::rmode { resolved_mode(cx, a.mode) }
-
-// Unifies `m1` and `m2`.  Returns unified value or failure code.
-pub fn unify_mode(cx: ctxt, modes: expected_found<ast::mode>)
-               -> Result<ast::mode, type_err> {
-    let m1 = modes.expected;
-    let m2 = modes.found;
-    match (canon_mode(cx, m1), canon_mode(cx, m2)) {
-      (m1, m2) if (m1 == m2) => {
-        result::Ok(m1)
-      }
-      (ast::infer(_), ast::infer(id2)) => {
-        cx.inferred_modes.insert(id2, m1);
-        result::Ok(m1)
-      }
-      (ast::infer(id), m) | (m, ast::infer(id)) => {
-        cx.inferred_modes.insert(id, m);
-        result::Ok(m1)
-      }
-      (_, _) => {
-        result::Err(terr_mode_mismatch(modes))
-      }
-    }
-}
-
-// If `m` was never unified, unifies it with `m_def`.  Returns the final value
-// for `m`.
-pub fn set_default_mode(cx: ctxt, m: ast::mode, m_def: ast::rmode) {
-    match canon_mode(cx, m) {
-      ast::infer(id) => {
-        cx.inferred_modes.insert(id, ast::expl(m_def));
-      }
-      ast::expl(_) => ()
-    }
-}
-
 pub fn ty_sort_str(cx: ctxt, t: t) -> ~str {
     match get(t).sty {
       ty_nil | ty_bot | ty_bool | ty_int(_) |
@@ -3537,11 +3439,6 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
                  *cx.sess.str_of(values.found))
         }
         terr_arg_count => ~"incorrect number of function parameters",
-        terr_mode_mismatch(values) => {
-            fmt!("expected argument mode %s, but found %s",
-                 pprust::mode_to_str(values.expected),
-                 pprust::mode_to_str(values.found))
-        }
         terr_regions_does_not_outlive(*) => {
             fmt!("lifetime mismatch")
         }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index ac745dce36d..ffaa6d46d33 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -501,52 +501,22 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
     return typ;
 }
 
-pub fn ty_of_arg<AC:AstConv,RS:region_scope + Copy + Durable>(
-        self: &AC,
-        rscope: &RS,
-        a: ast::arg,
-        expected_ty: Option<ty::arg>)
-     -> ty::arg {
+pub fn ty_of_arg<AC:AstConv,
+                 RS:region_scope + Copy + Durable>(
+                 self: &AC,
+                 rscope: &RS,
+                 a: ast::arg,
+                 expected_ty: Option<ty::arg>)
+                 -> ty::arg {
     let ty = match a.ty.node {
-      ast::ty_infer if expected_ty.is_some() => expected_ty.get().ty,
-      ast::ty_infer => self.ty_infer(a.ty.span),
-      _ => ast_ty_to_ty(self, rscope, a.ty)
-    };
-
-    let mode = {
-        match a.mode {
-          ast::infer(_) if expected_ty.is_some() => {
-            result::get(&ty::unify_mode(
-                self.tcx(),
-                ty::expected_found {expected: expected_ty.get().mode,
-                                    found: a.mode}))
-          }
-          ast::infer(_) => {
-            match ty::get(ty).sty {
-              // If the type is not specified, then this must be a fn expr.
-              // Leave the mode as infer(_), it will get inferred based
-              // on constraints elsewhere.
-              ty::ty_infer(_) => a.mode,
-
-              // If the type is known, then use the default for that type.
-              // Here we unify m and the default.  This should update the
-              // tables in tcx but should never fail, because nothing else
-              // will have been unified with m yet:
-              _ => {
-                let m1 = ast::expl(ty::default_arg_mode_for_ty(self.tcx(),
-                                                               ty));
-                result::get(&ty::unify_mode(
-                    self.tcx(),
-                    ty::expected_found {expected: m1,
-                                        found: a.mode}))
-              }
-            }
-          }
-          ast::expl(_) => a.mode
-        }
+        ast::ty_infer if expected_ty.is_some() => expected_ty.get().ty,
+        ast::ty_infer => self.ty_infer(a.ty.span),
+        _ => ast_ty_to_ty(self, rscope, a.ty),
     };
 
-    arg {mode: mode, ty: ty}
+    arg {
+        ty: ty
+    }
 }
 
 pub fn bound_lifetimes<AC:AstConv>(
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 40ad8bcb8b2..fb5b53d9400 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -96,7 +96,7 @@ use util::common::indenter;
 use core::hashmap::HashSet;
 use std::list::Nil;
 use syntax::ast::{def_id, sty_value, sty_region, sty_box};
-use syntax::ast::{sty_uniq, sty_static, node_id, by_copy, by_ref};
+use syntax::ast::{sty_uniq, sty_static, node_id};
 use syntax::ast::{m_const, m_mutbl, m_imm};
 use syntax::ast;
 use syntax::ast_map;
@@ -1051,9 +1051,9 @@ pub impl<'self> LookupContext<'self> {
         self.fcx.write_substs(self.callee_id, all_substs);
         method_map_entry {
             self_arg: arg {
-                mode: ast::expl(self_mode),
                 ty: candidate.rcvr_ty,
             },
+            self_mode: self_mode,
             explicit_self: candidate.method_ty.self_ty,
             origin: candidate.origin,
         }
@@ -1298,6 +1298,9 @@ pub impl<'self> LookupContext<'self> {
     }
 }
 
-pub fn get_mode_from_self_type(self_type: ast::self_ty_) -> ast::rmode {
-    match self_type { sty_value => by_copy, _ => by_ref }
+pub fn get_mode_from_self_type(self_type: ast::self_ty_) -> SelfMode {
+    match self_type {
+        sty_value => ty::ByCopy,
+        _ => ty::ByRef,
+    }
 }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index c6ab5affd10..7ce34bba29c 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1292,8 +1292,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
     }
 
     fn err_args(len: uint) -> ~[ty::arg] {
-        vec::from_fn(len, |_| ty::arg {mode: ast::expl(ast::by_copy),
-                                       ty: ty::mk_err()})
+        vec::from_fn(len, |_| ty::arg { ty: ty::mk_err() })
     }
 
     // A generic function for checking assignment expressions
@@ -1694,10 +1693,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         let fty = if error_happened {
             fty_sig = FnSig {
                 bound_lifetime_names: opt_vec::Empty,
-                inputs: fn_ty.sig.inputs.map(|an_arg| {
-                    arg { mode: an_arg.mode,
-                         ty: ty::mk_err()
-                        }}),
+                inputs: fn_ty.sig.inputs.map(|_| {
+                    arg {
+                        ty: ty::mk_err()
+                    }
+                }),
                 output: ty::mk_err()
             };
             ty::mk_err()
@@ -2762,11 +2762,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         };
         if bot_field {
             fcx.write_bot(id);
-        }
-        else if err_field {
+        } else if err_field {
             fcx.write_error(id);
-        }
-        else {
+        } else {
             let typ = ty::mk_tup(tcx, elt_ts);
             fcx.write_ty(id, typ);
         }
@@ -2796,15 +2794,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
           check_expr(fcx, idx);
           let raw_base_t = fcx.expr_ty(base);
           let idx_t = fcx.expr_ty(idx);
-          if ty::type_is_error(raw_base_t)
-              || ty::type_is_bot(raw_base_t) {
+          if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) {
               fcx.write_ty(id, raw_base_t);
-          }
-          else if ty::type_is_error(idx_t)
-              || ty::type_is_bot(idx_t) {
+          } else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) {
               fcx.write_ty(id, idx_t);
-          }
-          else {
+          } else {
               let (base_t, derefs) = do_autoderef(fcx, expr.span, raw_base_t);
               let base_sty = structure_of(fcx, expr.span, base_t);
               match ty::index_sty(&base_sty) {
@@ -2815,15 +2809,29 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                   }
                   None => {
                       let resolved = structurally_resolved_type(fcx,
-                          expr.span, raw_base_t);
-                      let ret_ty = lookup_op_method(fcx, expr, base, resolved,
-                                             tcx.sess.ident_of(~"index"),
-                                             ~[idx], DoDerefArgs, AutoderefReceiver,
-                        || {
-                            fcx.type_error_message(expr.span, |actual|
-                                fmt!("cannot index a value \
-                                      of type `%s`", actual), base_t, None);
-                        }, expected);
+                                                                expr.span,
+                                                                raw_base_t);
+                      let index_ident = tcx.sess.ident_of(~"index");
+                      let error_message = || {
+                        fcx.type_error_message(expr.span,
+                                               |actual| {
+                                                fmt!("cannot index a value \
+                                                      of type `%s`",
+                                                     actual)
+                                               },
+                                               base_t,
+                                               None);
+                      };
+                      let ret_ty = lookup_op_method(fcx,
+                                                    expr,
+                                                    base,
+                                                    resolved,
+                                                    index_ident,
+                                                    ~[idx],
+                                                    DoDerefArgs,
+                                                    AutoderefReceiver,
+                                                    error_message,
+                                                    expected);
                       fcx.write_ty(id, ret_ty);
                   }
               }
@@ -3180,8 +3188,8 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
                                    -> ty_param_bounds_and_ty {
 
     match defn {
-      ast::def_arg(nid, _, _) | ast::def_local(nid, _) |
-      ast::def_self(nid, _) | ast::def_binding(nid, _) => {
+      ast::def_arg(nid, _) | ast::def_local(nid, _) | ast::def_self(nid, _) |
+      ast::def_binding(nid, _) => {
           let typ = fcx.local_ty(sp, nid);
           return no_params(typ);
       }
@@ -3429,41 +3437,52 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
     fn param(ccx: @mut CrateCtxt, n: uint) -> ty::t {
         ty::mk_param(ccx.tcx, n, local_def(0))
     }
-    fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
-        arg {mode: ast::expl(m), ty: ty}
+    fn arg(ty: ty::t) -> ty::arg {
+        arg {
+            ty: ty
+        }
     }
+
     let tcx = ccx.tcx;
     let (n_tps, inputs, output) = match *ccx.tcx.sess.str_of(it.ident) {
       ~"size_of" |
       ~"pref_align_of" | ~"min_align_of" => (1u, ~[], ty::mk_uint()),
       ~"init" => (1u, ~[], param(ccx, 0u)),
-      ~"forget" => (1u, ~[arg(ast::by_copy, param(ccx, 0u))],
-                    ty::mk_nil()),
-      ~"transmute" => (2, ~[arg(ast::by_copy, param(ccx, 0))], param(ccx, 1)),
+      ~"forget" => (1u, ~[arg(param(ccx, 0u))], ty::mk_nil()),
+      ~"transmute" => (2, ~[ arg(param(ccx, 0)) ], param(ccx, 1)),
       ~"move_val" | ~"move_val_init" => {
-          (1u, ~[arg(ast::by_copy,
-                     ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
-                                     param(ccx, 0u))),
-               arg(ast::by_copy, param(ccx, 0u))],
+          (1u,
+           ~[
+            arg(ty::mk_mut_rptr(tcx,
+                                ty::re_bound(ty::br_anon(0)),
+                                param(ccx, 0))),
+               arg(param(ccx, 0u))
+            ],
          ty::mk_nil())
       }
       ~"needs_drop" => (1u, ~[], ty::mk_bool()),
 
       ~"atomic_cxchg"    | ~"atomic_cxchg_acq"| ~"atomic_cxchg_rel" => {
-        (0u, ~[arg(ast::by_copy,
-                   ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
-                                   ty::mk_int())),
-               arg(ast::by_copy, ty::mk_int()),
-               arg(ast::by_copy, ty::mk_int())],
-         ty::mk_int())
+        (0,
+         ~[
+            arg(ty::mk_mut_rptr(tcx,
+                                ty::re_bound(ty::br_anon(0)),
+                                ty::mk_int(tcx))),
+               arg(ty::mk_int()),
+               arg(ty::mk_int())
+         ],
+         ty::mk_int(tcx))
       }
       ~"atomic_xchg"     | ~"atomic_xadd"     | ~"atomic_xsub"     |
       ~"atomic_xchg_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
       ~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => {
-        (0u, ~[arg(ast::by_copy,
-                   ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
-                                   ty::mk_int())),
-               arg(ast::by_copy, ty::mk_int())],
+        (0,
+         ~[
+            arg(ty::mk_mut_rptr(tcx,
+                                ty::re_bound(ty::br_anon(0)),
+                                ty::mk_int(tcx))),
+            arg(ty::mk_int())
+         ],
          ty::mk_int())
       }
 
@@ -3472,14 +3491,15 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
         (1u, ~[], ty::mk_nil_ptr(ccx.tcx))
       }
       ~"visit_tydesc" => {
-          let tydesc_name = special_idents::tydesc;
-          assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
-          let (_, tydesc_ty) = *tcx.intrinsic_defs.get(&tydesc_name);
-          let (_, visitor_object_ty) = ty::visitor_object_ty(ccx.tcx);
-          let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {ty: tydesc_ty,
-                                                   mutbl: ast::m_imm});
-          (0u, ~[arg(ast::by_copy, td_ptr),
-                 arg(ast::by_copy, visitor_object_ty)], ty::mk_nil())
+        let tydesc_name = special_idents::tydesc;
+        assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
+        let (_, tydesc_ty) = *tcx.intrinsic_defs.get(&tydesc_name);
+        let (_, visitor_object_ty) = ty::visitor_object_ty(tcx);
+        let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
+            ty: tydesc_ty,
+            mutbl: ast::m_imm
+        });
+        (0, ~[ arg(td_ptr), arg(visitor_object_ty) ], ty::mk_nil())
       }
       ~"frame_address" => {
         let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy {
@@ -3489,233 +3509,124 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
             region: ty::re_bound(ty::br_anon(0)),
             sig: ty::FnSig {
                 bound_lifetime_names: opt_vec::Empty,
-                inputs: ~[arg {mode: ast::expl(ast::by_copy),
-                               ty: ty::mk_imm_ptr(
-                                   ccx.tcx,
-                                   ty::mk_mach_uint(ast::ty_u8))}],
+                inputs: ~[
+                    arg {
+                        ty: ty::mk_imm_ptr(ccx.tcx,
+                                           ty::mk_mach_uint(ast::ty_u8))
+                    }
+                ],
                 output: ty::mk_nil()
             }
         });
-        (0u, ~[arg(ast::by_copy, fty)], ty::mk_nil())
+        (0u, ~[ arg(fty) ], ty::mk_nil())
       }
       ~"morestack_addr" => {
         (0u, ~[], ty::mk_nil_ptr(ccx.tcx))
       }
       ~"memmove32" => {
-        (0, ~[arg(ast::by_copy,
-                  ty::mk_ptr(tcx,
-                    ty::mt { ty: ty::mk_u8(), mutbl: ast::m_mutbl })),
-              arg(ast::by_copy,
-                  ty::mk_ptr(tcx,
-                    ty::mt { ty: ty::mk_u8(), mutbl: ast::m_imm })),
-              arg(ast::by_copy,
-                  ty::mk_u32())],
+        (0,
+         ~[
+            arg(ty::mk_ptr(tcx, ty::mt {
+                ty: ty::mk_u8(),
+                mutbl: ast::m_mutbl
+            })),
+            arg(ty::mk_ptr(tcx, ty::mt {
+                ty: ty::mk_u8(),
+                mutbl: ast::m_imm
+            })),
+            arg(ty::mk_u32())
+         ],
          ty::mk_nil())
       }
       ~"memmove64" => {
-        (0, ~[arg(ast::by_copy,
-                  ty::mk_ptr(tcx,
-                    ty::mt { ty: ty::mk_u8(), mutbl: ast::m_mutbl })),
-              arg(ast::by_copy,
-                  ty::mk_ptr(tcx,
-                    ty::mt { ty: ty::mk_u8(), mutbl: ast::m_imm })),
-              arg(ast::by_copy,
-                  ty::mk_u64())],
-         ty::mk_nil())
-      }
-     ~"sqrtf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"sqrtf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"powif32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32()),
-               arg(ast::by_copy, ty::mk_i32())],
-         ty::mk_f32())
-     }
-     ~"powif64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64()),
-               arg(ast::by_copy, ty::mk_i32())],
-         ty::mk_f64())
-     }
-     ~"sinf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"sinf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"cosf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"cosf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"powf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32()),
-               arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"powf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64()),
-               arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"expf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"expf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"exp2f32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"exp2f64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"logf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"logf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"log10f32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"log10f64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"log2f32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"log2f64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"fmaf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32()),
-               arg(ast::by_copy, ty::mk_f32()),
-               arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"fmaf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64()),
-               arg(ast::by_copy, ty::mk_f64()),
-               arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"fabsf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"fabsf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"floorf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"floorf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"ceilf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"ceilf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"truncf32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f32())],
-         ty::mk_f32())
-     }
-     ~"truncf64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_f64())],
-         ty::mk_f64())
-     }
-     ~"ctpop8" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_i8())],
-         ty::mk_i8())
-     }
-     ~"ctpop16" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_i16())],
-         ty::mk_i16())
-     }
-     ~"ctpop32" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_i32())],
-         ty::mk_i32())
-     }
-     ~"ctpop64" => {
-        (0u, ~[arg(ast::by_copy, ty::mk_i64())],
-         ty::mk_i64())
-     }
-     ~"ctlz8" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i8())],
-         ty::mk_i8())
-     }
-     ~"ctlz16" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i16())],
-         ty::mk_i16())
-     }
-     ~"ctlz32" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i32())],
-         ty::mk_i32())
-     }
-     ~"ctlz64" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i64())],
-         ty::mk_i64())
-     }
-     ~"cttz8" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i8())],
-         ty::mk_i8())
-     }
-     ~"cttz16" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i16())],
-         ty::mk_i16())
-     }
-     ~"cttz32" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i32())],
-         ty::mk_i32())
-     }
-     ~"cttz64" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i64())],
-         ty::mk_i64())
-     }
-     ~"bswap16" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i16())],
-         ty::mk_i16())
-     }
-     ~"bswap32" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i32())],
-         ty::mk_i32())
-     }
-     ~"bswap64" => {
-         (0u, ~[arg(ast::by_copy, ty::mk_i64())],
-         ty::mk_i64())
-     }
-     ref other => {
-        tcx.sess.span_err(it.span, ~"unrecognized intrinsic function: `" +
-                          (*other) + ~"`");
-        return;
-      }
+        (0,
+         ~[arg(ty::mk_ptr(tcx, ty::mt {
+            ty: ty::mk_u8(),
+            mutbl: ast::m_mutbl
+           })),
+           arg(ty::mk_ptr(tcx, ty::mt {
+            ty: ty::mk_u8(),
+            mutbl: ast::m_imm
+           })),
+           arg(ty::mk_u64())
+         ],
+         ty::mk_nil(tcx))
+      }
+        ~"sqrtf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"sqrtf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"powif32" => {
+           (0,
+            ~[ arg(ty::mk_f32()), arg(ty::mk_i32()) ],
+            ty::mk_f32())
+        }
+        ~"powif64" => {
+           (0,
+            ~[ arg(ty::mk_f64()), arg(ty::mk_i32()) ],
+            ty::mk_f64())
+        }
+        ~"sinf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"sinf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"cosf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"cosf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"powf32" => {
+           (0,
+            ~[ arg(ty::mk_f32()), arg(ty::mk_f32()) ],
+            ty::mk_f32())
+        }
+        ~"powf64" => {
+           (0,
+            ~[ arg(ty::mk_f64()), arg(ty::mk_f64()) ],
+            ty::mk_f64())
+        }
+        ~"expf32"   => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"expf64"   => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"exp2f32"  => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"exp2f64"  => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"logf32"   => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"logf64"   => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"log10f32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"log10f64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"log2f32"  => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"log2f64"  => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"fmaf32" => {
+            (0,
+             ~[ arg(ty::mk_f32()), arg(ty::mk_f32()), arg(ty::mk_f32()) ],
+             ty::mk_f32())
+        }
+        ~"fmaf64" => {
+            (0,
+             ~[ arg(ty::mk_f64()), arg(ty::mk_f64()), arg(ty::mk_f64()) ],
+             ty::mk_f64())
+        }
+        ~"fabsf32"  => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"fabsf64"  => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"floorf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"floorf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"ceilf32"  => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"ceilf64"  => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"truncf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
+        ~"truncf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
+        ~"ctpop8"   => (0, ~[ arg(ty::mk_i8())  ], ty::mk_i8()),
+        ~"ctpop16"  => (0, ~[ arg(ty::mk_i16()) ], ty::mk_i16()),
+        ~"ctpop32"  => (0, ~[ arg(ty::mk_i32()) ], ty::mk_i32()),
+        ~"ctpop64"  => (0, ~[ arg(ty::mk_i64()) ], ty::mk_i64()),
+        ~"ctlz8"    => (0, ~[ arg(ty::mk_i8())  ], ty::mk_i8()),
+        ~"ctlz16"   => (0, ~[ arg(ty::mk_i16()) ], ty::mk_i16()),
+        ~"ctlz32"   => (0, ~[ arg(ty::mk_i32()) ], ty::mk_i32()),
+        ~"ctlz64"   => (0, ~[ arg(ty::mk_i64()) ], ty::mk_i64()),
+        ~"cttz8"    => (0, ~[ arg(ty::mk_i8())  ], ty::mk_i8()),
+        ~"cttz16"   => (0, ~[ arg(ty::mk_i16()) ], ty::mk_i16()),
+        ~"cttz32"   => (0, ~[ arg(ty::mk_i32()) ], ty::mk_i32()),
+        ~"cttz64"   => (0, ~[ arg(ty::mk_i64()) ], ty::mk_i64()),
+        ~"bswap16"  => (0, ~[ arg(ty::mk_i16()) ], ty::mk_i16()),
+        ~"bswap32"  => (0, ~[ arg(ty::mk_i32()) ], ty::mk_i32()),
+        ~"bswap64"  => (0, ~[ arg(ty::mk_i64()) ], ty::mk_i64()),
+        ref other => {
+            tcx.sess.span_err(it.span,
+                              ~"unrecognized intrinsic function: `" +
+                              (*other) + ~"`");
+            return;
+        }
     };
     let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
         purity: ast::unsafe_fn,
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 1cffd375f9b..cb2b854276d 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -55,7 +55,7 @@ pub type rvt = visit::vt<@mut Rcx>;
 fn encl_region_of_def(fcx: @mut FnCtxt, def: ast::def) -> ty::Region {
     let tcx = fcx.tcx();
     match def {
-        def_local(node_id, _) | def_arg(node_id, _, _) |
+        def_local(node_id, _) | def_arg(node_id, _) |
         def_self(node_id, _) | def_binding(node_id, _) => {
             tcx.region_maps.encl_region(node_id)
         }
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index 0b0f7515b6b..d6b09d1e7f4 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -66,7 +66,9 @@ fn resolve_method_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) {
             for resolve_type_vars_in_type(fcx, sp, mme.self_arg.ty).each |t| {
                 let method_map = fcx.ccx.method_map;
                 let new_entry = method_map_entry {
-                    self_arg: arg {mode: mme.self_arg.mode, ty: *t },
+                    self_arg: arg {
+                        ty: *t
+                    },
                     ..*mme
                 };
                 debug!("writeback::resolve_method_map_entry(id=%?, \
@@ -213,52 +215,55 @@ fn visit_stmt(s: @ast::stmt, wbcx: @mut WbCtxt, v: wb_vt) {
     resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s));
     visit::visit_stmt(s, wbcx, v);
 }
+
 fn visit_expr(e: @ast::expr, wbcx: @mut WbCtxt, v: wb_vt) {
-    if !wbcx.success { return; }
+    if !wbcx.success {
+        return;
+    }
+
     resolve_type_vars_for_node(wbcx, e.span, e.id);
     resolve_method_map_entry(wbcx.fcx, e.span, e.id);
     resolve_method_map_entry(wbcx.fcx, e.span, e.callee_id);
     resolve_vtable_map_entry(wbcx.fcx, e.span, e.id);
     resolve_vtable_map_entry(wbcx.fcx, e.span, e.callee_id);
+
     match e.node {
-      ast::expr_fn_block(ref decl, _) => {
-          for vec::each(decl.inputs) |input| {
-              let r_ty = resolve_type_vars_for_node(wbcx, e.span, input.id);
-
-              // Just in case we never constrained the mode to anything,
-              // constrain it to the default for the type in question.
-              match (r_ty, input.mode) {
-                  (Some(t), ast::infer(_)) => {
-                      let tcx = wbcx.fcx.ccx.tcx;
-                      let m_def = ty::default_arg_mode_for_ty(tcx, t);
-                      ty::set_default_mode(tcx, input.mode, m_def);
-                  }
-                  _ => ()
-              }
-          }
-      }
+        ast::expr_fn_block(ref decl, _) => {
+            for vec::each(decl.inputs) |input| {
+                let _ = resolve_type_vars_for_node(wbcx, e.span, input.id);
+            }
+        }
 
-      ast::expr_binary(*) | ast::expr_unary(*) | ast::expr_assign_op(*)
-        | ast::expr_index(*) => {
-        maybe_resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
-      }
+        ast::expr_binary(*) | ast::expr_unary(*) | ast::expr_assign_op(*) |
+        ast::expr_index(*) => {
+            maybe_resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
+        }
 
-      ast::expr_method_call(*) => {
-        // We must always have written in a callee ID type for these.
-        resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
-      }
+        ast::expr_method_call(*) => {
+            // We must always have written in a callee ID type for these.
+            resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
+        }
 
-      _ => ()
+        _ => ()
     }
+
     visit::visit_expr(e, wbcx, v);
 }
+
 fn visit_block(b: &ast::blk, wbcx: @mut WbCtxt, v: wb_vt) {
-    if !wbcx.success { return; }
+    if !wbcx.success {
+        return;
+    }
+
     resolve_type_vars_for_node(wbcx, b.span, b.node.id);
     visit::visit_block(b, wbcx, v);
 }
+
 fn visit_pat(p: @ast::pat, wbcx: @mut WbCtxt, v: wb_vt) {
-    if !wbcx.success { return; }
+    if !wbcx.success {
+        return;
+    }
+
     resolve_type_vars_for_node(wbcx, p.span, p.id);
     debug!("Type for pattern binding %s (id %d) resolved to %s",
            pat_to_str(p, wbcx.fcx.ccx.tcx.sess.intr()), p.id,
@@ -267,6 +272,7 @@ fn visit_pat(p: @ast::pat, wbcx: @mut WbCtxt, v: wb_vt) {
                                    p.id)));
     visit::visit_pat(p, wbcx, v);
 }
+
 fn visit_local(l: @ast::local, wbcx: @mut WbCtxt, v: wb_vt) {
     if !wbcx.success { return; }
     let var_ty = wbcx.fcx.local_ty(l.span, l.node.id);
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 828dfbb45cf..0ffd398d03c 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -552,10 +552,14 @@ pub fn compare_impl_method(tcx: ty::ctxt,
     // represent the self argument (unless this is a static method).
     // This argument will have the *transformed* self type.
     for trait_m.transformed_self_ty.each |&t| {
-        trait_fn_args.push(ty::arg {mode: ast::expl(ast::by_copy), ty: t});
+        trait_fn_args.push(ty::arg {
+            ty: t
+        });
     }
     for impl_m.transformed_self_ty.each |&t| {
-        impl_fn_args.push(ty::arg {mode: ast::expl(ast::by_copy), ty: t});
+        impl_fn_args.push(ty::arg {
+            ty: t
+        });
     }
 
     // Add in the normal arguments.
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index 58ad2fc1924..e4db423c2e3 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -95,7 +95,6 @@ pub trait Combine {
                    b: &ty::ClosureTy) -> cres<ty::ClosureTy>;
     fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig>;
     fn flds(&self, a: ty::field, b: ty::field) -> cres<ty::field>;
-    fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode>;
     fn args(&self, a: ty::arg, b: ty::arg) -> cres<ty::arg>;
     fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil>;
     fn purities(&self, a: purity, b: purity) -> cres<purity>;
@@ -312,28 +311,20 @@ pub fn super_flds<C:Combine>(
     }
 }
 
-pub fn super_modes<C:Combine>(
-    self: &C, a: ast::mode, b: ast::mode)
-    -> cres<ast::mode> {
-
-    let tcx = self.infcx().tcx;
-    ty::unify_mode(tcx, expected_found(self, a, b))
-}
-
-pub fn super_args<C:Combine>(
-    self: &C, a: ty::arg, b: ty::arg)
-    -> cres<ty::arg> {
-
-    do self.modes(a.mode, b.mode).chain |m| {
-        do self.contratys(a.ty, b.ty).chain |t| {
-            Ok(arg {mode: m, ty: t})
-        }
+pub fn super_args<C:Combine>(self: &C, a: ty::arg, b: ty::arg)
+                             -> cres<ty::arg> {
+    do self.contratys(a.ty, b.ty).chain |t| {
+        Ok(arg {
+            ty: t
+        })
     }
 }
 
-pub fn super_vstores<C:Combine>(
-    self: &C, vk: ty::terr_vstore_kind,
-    a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
+pub fn super_vstores<C:Combine>(self: &C,
+                                vk: ty::terr_vstore_kind,
+                                a: ty::vstore,
+                                b: ty::vstore)
+                                -> cres<ty::vstore> {
     debug!("%s.super_vstores(a=%?, b=%?)", self.tag(), a, b);
 
     match (a, b) {
diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs
index 78b3b097ae3..2bbcd24595c 100644
--- a/src/librustc/middle/typeck/infer/glb.rs
+++ b/src/librustc/middle/typeck/infer/glb.rs
@@ -152,10 +152,6 @@ impl Combine for Glb {
         super_trait_stores(self, vk, a, b)
     }
 
-    fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
-        super_modes(self, a, b)
-    }
-
     fn args(&self, a: ty::arg, b: ty::arg) -> cres<ty::arg> {
         super_args(self, a, b)
     }
diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs
index c79e530084f..85914338017 100644
--- a/src/librustc/middle/typeck/infer/lub.rs
+++ b/src/librustc/middle/typeck/infer/lub.rs
@@ -234,10 +234,6 @@ impl Combine for Lub {
         super_trait_stores(self, vk, a, b)
     }
 
-    fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
-        super_modes(self, a, b)
-    }
-
     fn args(&self, a: ty::arg, b: ty::arg) -> cres<ty::arg> {
         super_args(self, a, b)
     }
diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs
index b9541d4c066..266d157c4d0 100644
--- a/src/librustc/middle/typeck/infer/sub.rs
+++ b/src/librustc/middle/typeck/infer/sub.rs
@@ -241,14 +241,10 @@ impl Combine for Sub {
                     vk: ty::terr_vstore_kind,
                     a: ty::TraitStore,
                     b: ty::TraitStore)
-                 -> cres<ty::TraitStore> {
+                    -> cres<ty::TraitStore> {
         super_trait_stores(self, vk, a, b)
     }
 
-    fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
-        super_modes(self, a, b)
-    }
-
     fn args(&self, a: ty::arg, b: ty::arg) -> cres<ty::arg> {
         super_args(self, a, b)
     }
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 14ef3feb7d5..646b6412f55 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -116,10 +116,13 @@ pub struct method_param {
 }
 
 pub struct method_map_entry {
-    // the type and mode of the self parameter, which is not reflected
-    // in the fn type (FIXME #3446)
+    // the type of the self parameter, which is not reflected in the fn type
+    // (FIXME #3446)
     self_arg: ty::arg,
 
+    // the mode of `self`
+    self_mode: ty::SelfMode,
+
     // the type of explicit self on the method
     explicit_self: ast::self_ty_,
 
@@ -329,7 +332,6 @@ fn check_main_fn_ty(ccx: @mut CrateCtxt,
 fn check_start_fn_ty(ccx: @mut CrateCtxt,
                      start_id: ast::node_id,
                      start_span: span) {
-
     let tcx = ccx.tcx;
     let start_t = ty::node_id_to_type(tcx, start_id);
     match ty::get(start_t).sty {
@@ -351,19 +353,25 @@ fn check_start_fn_ty(ccx: @mut CrateCtxt,
                 _ => ()
             }
 
-            fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
-                ty::arg {mode: ast::expl(m), ty: ty}
+            fn arg(ty: ty::t) -> ty::arg {
+                ty::arg {
+                    ty: ty
+                }
             }
 
             let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
                 purity: ast::impure_fn,
                 abis: abi::AbiSet::Rust(),
-                sig: ty::FnSig {bound_lifetime_names: opt_vec::Empty,
-                            inputs: ~[arg(ast::by_copy, ty::mk_int()),
-                                      arg(ast::by_copy, ty::mk_imm_ptr(tcx,
-                                                            ty::mk_imm_ptr(tcx, ty::mk_u8()))),
-                                      arg(ast::by_copy, ty::mk_imm_ptr(tcx, ty::mk_u8()))],
-                            output: ty::mk_int()}
+                sig: ty::FnSig {
+                    bound_lifetime_names: opt_vec::Empty,
+                    inputs: ~[
+                        arg(ty::mk_int()),
+                        arg(ty::mk_imm_ptr(tcx,
+                                           ty::mk_imm_ptr(tcx, ty::mk_u8()))),
+                        arg(ty::mk_imm_ptr(tcx, ty::mk_u8()))
+                    ],
+                    output: ty::mk_int()
+                }
             });
 
             require_same_types(tcx, None, false, start_span, start_t, se_ty,
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index f0ea91c9153..aa8c3f8fd1b 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -8,28 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::ty;
-use middle::typeck;
-use middle::ty::canon_mode;
-use middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid,
-                 br_fresh};
-use middle::ty::{ctxt, field, method};
+use metadata::encoder;
+use middle::ty::{ReSkolemized, ReVar};
+use middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid};
+use middle::ty::{br_fresh, ctxt, field, method};
 use middle::ty::{mt, t, param_bound, param_ty};
 use middle::ty::{re_bound, re_free, re_scope, re_infer, re_static, Region};
-use middle::ty::{ReSkolemized, ReVar};
 use middle::ty::{ty_bool, ty_bot, ty_box, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_estr, ty_evec, ty_float, ty_bare_fn, ty_closure};
-use middle::ty::{ty_trait, ty_int};
 use middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param};
 use middle::ty::{ty_ptr, ty_rptr, ty_self, ty_tup, ty_type, ty_uniq};
+use middle::ty::{ty_trait, ty_int};
 use middle::ty::{ty_uint, ty_unboxed_vec, ty_infer};
-use metadata::encoder;
+use middle::ty;
+use middle::typeck;
+use syntax::abi::AbiSet;
+use syntax::ast_map;
 use syntax::codemap::span;
 use syntax::print::pprust;
-use syntax::print::pprust::mode_to_str;
 use syntax::{ast, ast_util};
-use syntax::ast_map;
-use syntax::abi::AbiSet;
 
 pub trait Repr {
     fn repr(&self, tcx: ctxt) -> ~str;
@@ -293,26 +290,14 @@ pub fn trait_ref_to_str(cx: ctxt, trait_ref: &ty::TraitRef) -> ~str {
 
 pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
     fn fn_input_to_str(cx: ctxt, input: ty::arg) -> ~str {
-        let ty::arg {mode: mode, ty: ty} = input;
-        let modestr = match canon_mode(cx, mode) {
-          ast::infer(_) => ~"",
-          ast::expl(m) => {
-            if !ty::type_needs_infer(ty) &&
-                m == ty::default_arg_mode_for_ty(cx, ty) {
-                ~""
-            } else {
-                mode_to_str(ast::expl(m)) + ~":"
-            }
-          }
-        };
-        fmt!("%s%s", modestr, ty_to_str(cx, ty))
+        ty_to_str(cx, input.ty)
     }
     fn bare_fn_to_str(cx: ctxt,
                       purity: ast::purity,
                       abis: AbiSet,
                       ident: Option<ast::ident>,
-                      sig: &ty::FnSig) -> ~str
-    {
+                      sig: &ty::FnSig)
+                      -> ~str {
         let mut s = ~"extern ";
 
         s.push_str(abis.to_str());
@@ -701,7 +686,7 @@ impl Repr for typeck::method_map_entry {
 
 impl Repr for ty::arg {
     fn repr(&self, tcx: ctxt) -> ~str {
-        fmt!("%?(%s)", self.mode, self.ty.repr(tcx))
+        fmt!("(%s)", self.ty.repr(tcx))
     }
 }
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 4137b3b8aa1..ba6fe1cda4f 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -198,7 +198,7 @@ pub enum def {
     def_mod(def_id),
     def_foreign_mod(def_id),
     def_const(def_id),
-    def_arg(node_id, mode, bool /* is_mutbl */),
+    def_arg(node_id, bool /* is_mutbl */),
     def_local(node_id, bool /* is_mutbl */),
     def_variant(def_id /* enum */, def_id /* variant */),
     def_ty(def_id),
@@ -417,43 +417,6 @@ pub enum unop {
     neg
 }
 
-// Generally, after typeck you can get the inferred value
-// using ty::resolved_T(...).
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
-pub enum inferable<T> {
-    expl(T),
-    infer(node_id)
-}
-
-impl<T:to_bytes::IterBytes> to_bytes::IterBytes for inferable<T> {
-    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
-        match *self {
-          expl(ref t) =>
-          to_bytes::iter_bytes_2(&0u8, t, lsb0, f),
-
-          infer(ref n) =>
-          to_bytes::iter_bytes_2(&1u8, n, lsb0, f),
-        }
-    }
-}
-
-// "resolved" mode: the real modes.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
-pub enum rmode { by_ref, by_copy }
-
-impl to_bytes::IterBytes for rmode {
-    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
-        (*self as u8).iter_bytes(lsb0, f)
-    }
-}
-
-// inferable mode.
-pub type mode = inferable<rmode>;
-
 pub type stmt = spanned<stmt_>;
 
 #[auto_encode]
@@ -941,7 +904,6 @@ pub struct inline_asm {
 #[auto_decode]
 #[deriving(Eq)]
 pub struct arg {
-    mode: mode,
     is_mutbl: bool,
     ty: @Ty,
     pat: @pat,
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index c28d369e7f8..148b713a4f5 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -58,7 +58,7 @@ pub fn def_id_of_def(d: def) -> def_id {
       def_use(id) | def_struct(id) | def_trait(id) => {
         id
       }
-      def_arg(id, _, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id)
+      def_arg(id, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id)
       | def_upvar(id, _, _, _) | def_binding(id, _) | def_region(id)
       | def_typaram_binder(id) | def_label(id) => {
         local_def(id)
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 0d451c66edb..da7b9570131 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -608,7 +608,6 @@ fn mk_ser_method(
     };
 
     let ser_inputs = ~[ast::arg {
-        mode: ast::infer(cx.next_id()),
         is_mutbl: false,
         ty: ty_s,
         pat: @ast::pat {
@@ -670,20 +669,22 @@ fn mk_deser_method(
         span: span,
     };
 
-    let deser_inputs = ~[ast::arg {
-        mode: ast::infer(cx.next_id()),
-        is_mutbl: false,
-        ty: ty_d,
-        pat: @ast::pat {
+    let deser_inputs = ~[
+        ast::arg {
+            is_mutbl: false,
+            ty: ty_d,
+            pat: @ast::pat {
+                id: cx.next_id(),
+                node: ast::pat_ident(ast::bind_by_copy,
+                                     ast_util::ident_to_path(span,
+                                                             cx.ident_of(
+                                                                ~"__d")),
+                                     None),
+                span: span,
+            },
             id: cx.next_id(),
-            node: ast::pat_ident(
-                ast::bind_by_copy,
-                ast_util::ident_to_path(span, cx.ident_of(~"__d")),
-                None),
-            span: span,
-        },
-        id: cx.next_id(),
-    }];
+        }
+    ];
 
     let deser_decl = ast::fn_decl {
         inputs: deser_inputs,
@@ -1120,7 +1121,6 @@ fn mk_enum_deser_body(
         ast::expr_fn_block(
             ast::fn_decl {
                 inputs: ~[ast::arg {
-                    mode: ast::infer(ext_cx.next_id()),
                     is_mutbl: false,
                     ty: @ast::Ty {
                         id: ext_cx.next_id(),
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index c4c2fed778f..4c876669f47 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -419,7 +419,6 @@ pub fn mk_arg(cx: @ext_ctxt,
            -> ast::arg {
     let arg_pat = mk_pat_ident(cx, span, ident);
     ast::arg {
-        mode: ast::infer(cx.next_id()),
         is_mutbl: false,
         ty: ty,
         pat: arg_pat,
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index ede3711b052..deaf1b1c754 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -196,7 +196,6 @@ impl ext_ctxt_ast_builder for @ext_ctxt {
 
     fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg {
         ast::arg {
-            mode: ast::infer(self.next_id()),
             is_mutbl: false,
             ty: ty,
             pat: @ast::pat {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index da6d0e8bf7b..cee1f531176 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -105,7 +105,6 @@ fn fold_attribute_(at: attribute, fld: @ast_fold) -> attribute {
 //used in noop_fold_foreign_item and noop_fold_fn_decl
 fn fold_arg_(a: arg, fld: @ast_fold) -> arg {
     ast::arg {
-        mode: a.mode,
         is_mutbl: a.is_mutbl,
         ty: fld.fold_ty(a.ty),
         pat: fld.fold_pat(a.pat),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 30275436c06..ae374808270 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -17,10 +17,10 @@ use ast::{RegionTyParamBound, TraitTyParamBound};
 use ast::{provided, public, purity};
 use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer};
 use ast::{bind_by_copy, bitand, bitor, bitxor, blk};
-use ast::{blk_check_mode, box, by_copy, by_ref};
+use ast::{blk_check_mode, box};
 use ast::{crate, crate_cfg, decl, decl_item};
 use ast::{decl_local, default_blk, deref, quot, enum_def};
-use ast::{expl, expr, expr_, expr_addr_of, expr_match, expr_again};
+use ast::{expr, expr_, expr_addr_of, expr_match, expr_again};
 use ast::{expr_assign, expr_assign_op, expr_binary, expr_block};
 use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body};
 use ast::{expr_field, expr_fn_block, expr_if, expr_index};
@@ -32,13 +32,13 @@ use ast::{expr_vstore_slice, expr_vstore_box};
 use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
 use ast::{expr_vstore_uniq, TyClosure, TyBareFn, Onceness, Once, Many};
 use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod};
-use ast::{ident, impure_fn, infer, inherited, item, item_, item_const};
+use ast::{ident, impure_fn, inherited, item, item_, item_const};
 use ast::{item_const, item_enum, item_fn, item_foreign_mod, item_impl};
 use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
 use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int};
 use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const};
 use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal};
-use ast::{match_seq, match_tok, method, mode, mt, mul, mutability};
+use ast::{match_seq, match_tok, method, mt, mul, mutability};
 use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum};
 use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct};
 use ast::{pat_tup, pat_uniq, pat_wild, private};
@@ -765,22 +765,22 @@ pub impl Parser {
     }
 
     // parse an optional mode.
-    fn parse_arg_mode(&self) -> mode {
+    // XXX: Remove after snapshot.
+    fn parse_arg_mode(&self) {
         if self.eat(&token::BINOP(token::MINUS)) {
             self.obsolete(*self.span, ObsoleteMode);
-            expl(by_copy)
         } else if self.eat(&token::ANDAND) {
-            expl(by_ref)
+            // Ignore.
         } else if self.eat(&token::BINOP(token::PLUS)) {
             if self.eat(&token::BINOP(token::PLUS)) {
                 // ++ mode is obsolete, but we need a snapshot
                 // to stop parsing it.
-                expl(by_copy)
+                // Ignore.
             } else {
-                expl(by_copy)
+                // Ignore.
             }
         } else {
-            infer(self.get_id())
+            // Ignore.
         }
     }
 
@@ -810,16 +810,14 @@ pub impl Parser {
     // This version of parse arg doesn't necessarily require
     // identifier names.
     fn parse_arg_general(&self, require_name: bool) -> arg {
-        let m;
         let mut is_mutbl = false;
         let pat = if require_name || self.is_named_argument() {
-            m = self.parse_arg_mode();
+            self.parse_arg_mode();
             is_mutbl = self.eat_keyword(&~"mut");
             let pat = self.parse_pat(false);
             self.expect(&token::COLON);
             pat
         } else {
-            m = infer(self.get_id());
             ast_util::ident_to_pat(self.get_id(),
                                    *self.last_span,
                                    special_idents::invalid)
@@ -827,8 +825,12 @@ pub impl Parser {
 
         let t = self.parse_ty(false);
 
-        ast::arg { mode: m, is_mutbl: is_mutbl,
-                  ty: t, pat: pat, id: self.get_id() }
+        ast::arg {
+            is_mutbl: is_mutbl,
+            ty: t,
+            pat: pat,
+            id: self.get_id(),
+        }
     }
 
     // parse a single function argument
@@ -838,7 +840,7 @@ pub impl Parser {
 
     // parse an argument in a lambda header e.g. |arg, arg|
     fn parse_fn_block_arg(&self) -> arg_or_capture_item {
-        let m = self.parse_arg_mode();
+        self.parse_arg_mode();
         let is_mutbl = self.eat_keyword(&~"mut");
         let pat = self.parse_pat(false);
         let t = if self.eat(&token::COLON) {
@@ -851,7 +853,6 @@ pub impl Parser {
             }
         };
         either::Left(ast::arg {
-            mode: m,
             is_mutbl: is_mutbl,
             ty: t,
             pat: pat,
@@ -2440,18 +2441,21 @@ pub impl Parser {
 
     // used by the copy foo and ref foo patterns to give a good
     // error message when parsing mistakes like ref foo(a,b)
-    fn parse_pat_ident(&self, refutable: bool,
-                       binding_mode: ast::binding_mode) -> ast::pat_ {
+    fn parse_pat_ident(&self,
+                       refutable: bool,
+                       binding_mode: ast::binding_mode)
+                       -> ast::pat_ {
         if !is_plain_ident(&*self.token) {
-            self.span_fatal(
-                *self.last_span,
-                ~"expected identifier, found path");
+            self.span_fatal(*self.last_span,
+                            ~"expected identifier, found path");
         }
         // why a path here, and not just an identifier?
         let name = self.parse_path_without_tps();
         let sub = if self.eat(&token::AT) {
             Some(self.parse_pat(refutable))
-        } else { None };
+        } else {
+            None
+        };
 
         // just to be friendly, if they write something like
         //   ref Some(i)
@@ -4406,10 +4410,11 @@ pub impl Parser {
     // text that can't be parsed as an item
     // - mod_items uses extern_mod_allowed = true
     // - block_tail_ uses extern_mod_allowed = false
-    fn parse_items_and_view_items(&self, first_item_attrs: ~[attribute],
+    fn parse_items_and_view_items(&self,
+                                  first_item_attrs: ~[attribute],
                                   mut extern_mod_allowed: bool,
                                   macros_allowed: bool)
-                                -> ParsedItemsAndViewItems {
+                                  -> ParsedItemsAndViewItems {
         let mut attrs = vec::append(first_item_attrs,
                                     self.parse_outer_attributes());
         // First, parse view items.
@@ -4539,8 +4544,11 @@ pub impl Parser {
 
     fn parse_str(&self) -> @~str {
         match *self.token {
-          token::LIT_STR(s) => { self.bump(); self.id_to_str(s) }
-          _ =>  self.fatal(~"expected string literal")
+            token::LIT_STR(s) => {
+                self.bump();
+                self.id_to_str(s)
+            }
+            _ =>  self.fatal(~"expected string literal")
         }
     }
 }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 918fc805194..337355304d4 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1718,19 +1718,6 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) {
     maybe_print_comment(s, decl.output.span.lo);
 }
 
-pub fn mode_to_str(m: ast::mode) -> ~str {
-    match m {
-      ast::expl(ast::by_ref) => ~"&&",
-      ast::expl(ast::by_copy) => ~"+",
-      ast::infer(_) => ~""
-    }
-}
-
-pub fn print_arg_mode(s: @ps, m: ast::mode) {
-    let ms = mode_to_str(m);
-    if ms != ~"" { word(s.s, ms); }
-}
-
 pub fn print_bounds(s: @ps, bounds: @OptVec<ast::TyParamBound>) {
     if !bounds.is_empty() {
         word(s.s, ~":");
@@ -1879,7 +1866,6 @@ pub fn print_mt(s: @ps, mt: &ast::mt) {
 
 pub fn print_arg(s: @ps, input: ast::arg) {
     ibox(s, indent_unit);
-    print_arg_mode(s, input.mode);
     if input.is_mutbl {
         word_space(s, ~"mut");
     }