about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-12-03 13:30:02 -0500
committerNiko Matsakis <niko@alum.mit.edu>2014-12-25 07:04:07 -0500
commita583ba2fa007b27a92a1be676b271aefcb250128 (patch)
treefa97a1e9d2514dbb7fd37de3e7bd3b05bb0403c8 /src
parent8f770f10b2740ff1fb2be938f37ef4f35f8bf4ca (diff)
downloadrust-a583ba2fa007b27a92a1be676b271aefcb250128.tar.gz
rust-a583ba2fa007b27a92a1be676b271aefcb250128.zip
Remove `McResult` from the mem-categorization interface.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/expr_use_visitor.rs100
-rw-r--r--src/librustc/middle/mem_categorization.rs155
-rw-r--r--src/librustc/middle/traits/select.rs3
-rw-r--r--src/librustc/middle/ty.rs8
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs7
-rw-r--r--src/librustc_trans/trans/common.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs14
-rw-r--r--src/librustc_typeck/check/regionck.rs42
8 files changed, 135 insertions, 202 deletions
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 6ec9171057b..e3f4d7056bd 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -302,22 +302,6 @@ pub struct ExprUseVisitor<'d,'t,'tcx,TYPER:'t> {
     param_env: ParameterEnvironment<'tcx>,
 }
 
-// If the TYPER results in an error, it's because the type check
-// failed (or will fail, when the error is uncovered and reported
-// during writeback). In this case, we just ignore this part of the
-// code.
-//
-// Note that this macro appears similar to try!(), but, unlike try!(),
-// it does not propagate the error.
-macro_rules! return_if_err {
-    ($inp: expr) => (
-        match $inp {
-            Ok(v) => v,
-            Err(()) => return
-        }
-    )
-}
-
 /// Whether the elements of an overloaded operation are passed by value or by reference
 enum PassArgs {
     ByValue,
@@ -348,7 +332,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                          decl: &ast::FnDecl,
                          body: &ast::Block) {
         for arg in decl.inputs.iter() {
-            let arg_ty = return_if_err!(self.typer.node_ty(arg.pat.id));
+            let arg_ty = self.typer.node_ty(arg.pat.id);
 
             let fn_body_scope = region::CodeExtent::from_node_id(body.id);
             let arg_cmt = self.mc.cat_rvalue(
@@ -385,7 +369,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     pub fn consume_expr(&mut self, expr: &ast::Expr) {
         debug!("consume_expr(expr={})", expr.repr(self.tcx()));
 
-        let cmt = return_if_err!(self.mc.cat_expr(expr));
+        let cmt = self.mc.cat_expr(expr);
         self.delegate_consume(expr.id, expr.span, cmt);
         self.walk_expr(expr);
     }
@@ -394,7 +378,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                    assignment_expr: &ast::Expr,
                    expr: &ast::Expr,
                    mode: MutateMode) {
-        let cmt = return_if_err!(self.mc.cat_expr(expr));
+        let cmt = self.mc.cat_expr(expr);
         self.delegate.mutate(assignment_expr.id, assignment_expr.span, cmt, mode);
         self.walk_expr(expr);
     }
@@ -407,7 +391,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
         debug!("borrow_expr(expr={}, r={}, bk={})",
                expr.repr(self.tcx()), r.repr(self.tcx()), bk.repr(self.tcx()));
 
-        let cmt = return_if_err!(self.mc.cat_expr(expr));
+        let cmt = self.mc.cat_expr(expr);
         self.delegate.borrow(expr.id, expr.span, cmt, r, bk, cause);
 
         // Note: Unlike consume, we can ignore ExprParen. cat_expr
@@ -500,7 +484,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
             }
 
             ast::ExprMatch(ref discr, ref arms, _) => {
-                let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr));
+                let discr_cmt = self.mc.cat_expr(&**discr);
                 self.borrow_expr(&**discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant);
 
                 // treatment of the discriminant is handled while walking the arms.
@@ -559,7 +543,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
 
                 // Fetch the type of the value that the iteration yields to
                 // produce the pattern's categorized mutable type.
-                let pattern_type = return_if_err!(self.typer.node_ty(pat.id));
+                let pattern_type = self.typer.node_ty(pat.id);
                 let blk_scope = region::CodeExtent::from_node_id(blk.id);
                 let pat_cmt = self.mc.cat_rvalue(pat.id,
                                                  pat.span,
@@ -647,7 +631,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     }
 
     fn walk_callee(&mut self, call: &ast::Expr, callee: &ast::Expr) {
-        let callee_ty = return_if_err!(self.typer.expr_ty_adjusted(callee));
+        let callee_ty = self.typer.expr_ty_adjusted(callee);
         debug!("walk_callee: callee={} callee_ty={}",
                callee.repr(self.tcx()), callee_ty.repr(self.tcx()));
         let call_scope = region::CodeExtent::from_node_id(call.id);
@@ -747,7 +731,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                 // "assigns", which is handled by
                 // `walk_pat`:
                 self.walk_expr(&**expr);
-                let init_cmt = return_if_err!(self.mc.cat_expr(&**expr));
+                let init_cmt = self.mc.cat_expr(&**expr);
                 self.walk_irrefutable_pat(init_cmt, &*local.pat);
             }
         }
@@ -781,7 +765,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
             None => { return; }
         };
 
-        let with_cmt = return_if_err!(self.mc.cat_expr(&*with_expr));
+        let with_cmt = self.mc.cat_expr(&*with_expr);
 
         // Select just those fields of the `with`
         // expression that will actually be used
@@ -836,7 +820,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                         // rvalue.
                         debug!("walk_adjustment(AutoAddEnv|AdjustReifyFnPointer)");
                         let cmt_unadjusted =
-                            return_if_err!(self.mc.cat_expr_unadjusted(expr));
+                            self.mc.cat_expr_unadjusted(expr);
                         self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
                     }
                     ty::AdjustDerefRef(ty::AutoDerefRef {
@@ -870,7 +854,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
             match self.typer.node_method_ty(deref_id) {
                 None => {}
                 Some(method_ty) => {
-                    let cmt = return_if_err!(self.mc.cat_expr_autoderefd(expr, i));
+                    let cmt = self.mc.cat_expr_autoderefd(expr, i);
                     let self_ty = ty::ty_fn_args(method_ty)[0];
                     let (m, r) = match self_ty.sty {
                         ty::ty_rptr(r, ref m) => (m.mutbl, r),
@@ -900,15 +884,14 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                 assert!(n == 1, format!("Expected exactly 1 deref with Uniq \
                                          AutoRefs, found: {}", n));
                 let cmt_unadjusted =
-                    return_if_err!(self.mc.cat_expr_unadjusted(expr));
+                    self.mc.cat_expr_unadjusted(expr);
                 self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
                 return;
             }
             _ => {}
         }
 
-        let cmt_derefd = return_if_err!(
-            self.mc.cat_expr_autoderefd(expr, n));
+        let cmt_derefd = self.mc.cat_expr_autoderefd(expr, n);
         debug!("walk_adjustment: cmt_derefd={}",
                cmt_derefd.repr(self.tcx()));
 
@@ -1001,7 +984,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                                mode: &mut TrackMatchMode<Span>) {
         debug!("determine_pat_move_mode cmt_discr={} pat={}", cmt_discr.repr(self.tcx()),
                pat.repr(self.tcx()));
-        return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| {
+        self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| {
             let tcx = self.typer.tcx();
             let def_map = &self.typer.tcx().def_map;
             if pat_util::pat_is_binding(def_map, pat) {
@@ -1024,7 +1007,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                     }
                 }
             }
-        }));
+        });
     }
 
     /// The core driver for walking a pattern; `match_mode` must be
@@ -1039,11 +1022,11 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
 
         let mc = &self.mc;
         let typer = self.typer;
-        let tcx = typer.tcx();
         let def_map = &self.typer.tcx().def_map;
         let delegate = &mut self.delegate;
         let param_env = &mut self.param_env;
-        return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
+
+        mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
             if pat_util::pat_is_binding(def_map, pat) {
                 let tcx = typer.tcx();
 
@@ -1053,17 +1036,13 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                        match_mode);
 
                 // pat_ty: the type of the binding being produced.
-                let pat_ty = return_if_err!(typer.node_ty(pat.id));
+                let pat_ty = typer.node_ty(pat.id);
 
                 // Each match binding is effectively an assignment to the
                 // binding being produced.
                 let def = def_map.borrow()[pat.id].clone();
-                match mc.cat_def(pat.id, pat.span, pat_ty, def) {
-                    Ok(binding_cmt) => {
-                        delegate.mutate(pat.id, pat.span, binding_cmt, Init);
-                    }
-                    Err(_) => { }
-                }
+                let binding_cmt = mc.cat_def(pat.id, pat.span, pat_ty, def);
+                delegate.mutate(pat.id, pat.span, binding_cmt, Init);
 
                 // It is also a borrow or copy/move of the value being matched.
                 match pat.node {
@@ -1097,15 +1076,8 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                         // borrow of the elements of the vector being
                         // matched.
 
-                        let (slice_cmt, slice_mutbl, slice_r) = {
-                            match mc.cat_slice_pattern(cmt_pat, &**slice_pat) {
-                                Ok(v) => v,
-                                Err(()) => {
-                                    tcx.sess.span_bug(slice_pat.span,
-                                                      "Err from mc")
-                                }
-                            }
-                        };
+                        let (slice_cmt, slice_mutbl, slice_r) =
+                            mc.cat_slice_pattern(cmt_pat, &**slice_pat);
 
                         // Note: We declare here that the borrow
                         // occurs upon entering the `[...]`
@@ -1135,13 +1107,13 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                     _ => { }
                 }
             }
-        }));
+        });
 
         // Do a second pass over the pattern, calling `matched_pat` on
         // the interior nodes (enum variants and structs), as opposed
         // to the above loop's visit of than the bindings that form
         // the leaves of the pattern tree structure.
-        return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
+        mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
             let def_map = def_map.borrow();
             let tcx = typer.tcx();
 
@@ -1222,7 +1194,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                     // cases either.
                 }
             }
-        }));
+        });
     }
 
     fn walk_captures(&mut self, closure_expr: &ast::Expr) {
@@ -1246,9 +1218,9 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                             freevars: &[ty::Freevar]) {
         for freevar in freevars.iter() {
             let id_var = freevar.def.def_id().node;
-            let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
-                                                               closure_expr.span,
-                                                               freevar.def));
+            let cmt_var = self.cat_captured_var(closure_expr.id,
+                                                closure_expr.span,
+                                                freevar.def);
 
             // Lookup the kind of borrow the callee requires, as
             // inferred by regionbk
@@ -1269,13 +1241,11 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                               closure_expr: &ast::Expr,
                               freevars: &[ty::Freevar]) {
         for freevar in freevars.iter() {
-            let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
-                                                               closure_expr.span,
-                                                               freevar.def));
-            let mode = copy_or_move(self.tcx(),
-                                    cmt_var.ty,
-                                    &self.param_env,
-                                    CaptureMove);
+            let cmt_var = self.cat_captured_var(closure_expr.id,
+                                                closure_expr.span,
+                                                freevar.def);
+            let mode = copy_or_move(self.tcx(), cmt_var.ty,
+                                    &self.param_env, CaptureMove);
             self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode);
         }
     }
@@ -1284,11 +1254,11 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                         closure_id: ast::NodeId,
                         closure_span: Span,
                         upvar_def: def::Def)
-                        -> mc::McResult<mc::cmt<'tcx>> {
+                        -> mc::cmt<'tcx> {
         // Create the cmt for the variable being borrowed, from the
         // caller's perspective
         let var_id = upvar_def.def_id().node;
-        let var_ty = try!(self.typer.node_ty(var_id));
+        let var_ty = self.typer.node_ty(var_id);
         self.mc.cat_def(closure_id, closure_span, var_ty, upvar_def)
     }
 }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 7dadd832ca2..eff5433c3e5 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -264,8 +264,6 @@ pub struct MemCategorizationContext<'t,TYPER:'t> {
 
 impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
 
-pub type McResult<T> = Result<T, ()>;
-
 /// The `Typer` trait provides the interface for the mem-categorization
 /// module to the results of the type check. It can be used to query
 /// the type assigned to an expression node, to inquire after adjustments,
@@ -284,8 +282,8 @@ pub type McResult<T> = Result<T, ()>;
 /// can be sure that only `Ok` results will occur.
 pub trait Typer<'tcx> {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
-    fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
-    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>>;
+    fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx>;
+    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx>;
     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>>;
     fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
     fn is_method_call(&self, id: ast::NodeId) -> bool;
@@ -375,15 +373,6 @@ impl MutabilityCategory {
     }
 }
 
-macro_rules! if_ok {
-    ($inp: expr) => (
-        match $inp {
-            Ok(v) => { v }
-            Err(e) => { return Err(e); }
-        }
-    )
-}
-
 impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
     pub fn new(typer: &'t TYPER) -> MemCategorizationContext<'t,TYPER> {
         MemCategorizationContext { typer: typer }
@@ -393,22 +382,22 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         self.typer.tcx()
     }
 
-    fn expr_ty(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
+    fn expr_ty(&self, expr: &ast::Expr) -> Ty<'tcx> {
         self.typer.node_ty(expr.id)
     }
 
-    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
-        let unadjusted_ty = if_ok!(self.expr_ty(expr));
-        Ok(ty::adjust_ty(self.tcx(), expr.span, expr.id, unadjusted_ty,
-                         self.typer.adjustments().borrow().get(&expr.id),
-                         |method_call| self.typer.node_method_ty(method_call)))
+    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
+        let unadjusted_ty = self.expr_ty(expr);
+        ty::adjust_ty(self.tcx(), expr.span, expr.id, unadjusted_ty,
+                      self.typer.adjustments().borrow().get(&expr.id),
+                      |method_call| self.typer.node_method_ty(method_call))
     }
 
-    fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
+    fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
         self.typer.node_ty(id)
     }
 
-    fn pat_ty(&self, pat: &ast::Pat) -> McResult<Ty<'tcx>> {
+    fn pat_ty(&self, pat: &ast::Pat) -> Ty<'tcx> {
         let tcx = self.typer.tcx();
         let base_ty = self.typer.node_ty(pat.id);
         // FIXME (Issue #18207): This code detects whether we are
@@ -420,11 +409,9 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                 // a bind-by-ref means that the base_ty will be the type of the ident itself,
                 // but what we want here is the type of the underlying value being borrowed.
                 // So peel off one-level, turning the &T into T.
-                base_ty.map(|t| {
-                    ty::deref(t, false).unwrap_or_else(|| {
-                        panic!("encountered BindByRef with non &-type");
-                    }).ty
-                })
+                ty::deref(base_ty, false).unwrap_or_else(|| {
+                    panic!("encountered BindByRef with non &-type");
+                }).ty
             }
             _ => base_ty,
         };
@@ -433,7 +420,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         ret_ty
     }
 
-    pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
+    pub fn cat_expr(&self, expr: &ast::Expr) -> cmt<'tcx> {
         match self.typer.adjustments().borrow().get(&expr.id) {
             None => {
                 // No adjustments.
@@ -447,8 +434,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                expr.repr(self.tcx()));
                         // Convert a bare fn to a closure by adding NULL env.
                         // Result is an rvalue.
-                        let expr_ty = if_ok!(self.expr_ty_adjusted(expr));
-                        Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
+                        let expr_ty = self.expr_ty_adjusted(expr);
+                        self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
                     }
 
                     ty::AdjustDerefRef(
@@ -458,8 +445,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                expr.repr(self.tcx()));
                         // Equivalent to &*expr or something similar.
                         // Result is an rvalue.
-                        let expr_ty = if_ok!(self.expr_ty_adjusted(expr));
-                        Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
+                        let expr_ty = self.expr_ty_adjusted(expr);
+                        self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
                     }
 
                     ty::AdjustDerefRef(
@@ -476,39 +463,39 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
     pub fn cat_expr_autoderefd(&self,
                                expr: &ast::Expr,
                                autoderefs: uint)
-                               -> McResult<cmt<'tcx>> {
-        let mut cmt = if_ok!(self.cat_expr_unadjusted(expr));
+                               -> cmt<'tcx> {
+        let mut cmt = self.cat_expr_unadjusted(expr);
         debug!("cat_expr_autoderefd: autoderefs={}, cmt={}",
                autoderefs,
                cmt.repr(self.tcx()));
         for deref in range(1u, autoderefs + 1) {
             cmt = self.cat_deref(expr, cmt, deref, false);
         }
-        return Ok(cmt);
+        return cmt;
     }
 
-    pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
+    pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> cmt<'tcx> {
         debug!("cat_expr: id={} expr={}", expr.id, expr.repr(self.tcx()));
 
-        let expr_ty = if_ok!(self.expr_ty(expr));
+        let expr_ty = self.expr_ty(expr);
         match expr.node {
           ast::ExprUnary(ast::UnDeref, ref e_base) => {
-            let base_cmt = if_ok!(self.cat_expr(&**e_base));
-            Ok(self.cat_deref(expr, base_cmt, 0, false))
+            let base_cmt = self.cat_expr(&**e_base);
+            self.cat_deref(expr, base_cmt, 0, false)
           }
 
           ast::ExprField(ref base, f_name) => {
-            let base_cmt = if_ok!(self.cat_expr(&**base));
+            let base_cmt = self.cat_expr(&**base);
             debug!("cat_expr(cat_field): id={} expr={} base={}",
                    expr.id,
                    expr.repr(self.tcx()),
                    base_cmt.repr(self.tcx()));
-            Ok(self.cat_field(expr, base_cmt, f_name.node.name, expr_ty))
+            self.cat_field(expr, base_cmt, f_name.node.name, expr_ty)
           }
 
           ast::ExprTupField(ref base, idx) => {
-            let base_cmt = if_ok!(self.cat_expr(&**base));
-            Ok(self.cat_tup_field(expr, base_cmt, idx.node, expr_ty))
+            let base_cmt = self.cat_expr(&**base);
+            self.cat_tup_field(expr, base_cmt, idx.node, expr_ty)
           }
 
           ast::ExprIndex(ref base, _) => {
@@ -518,14 +505,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                     // If this is an index implemented by a method call, then it will
                     // include an implicit deref of the result.
                     let ret_ty = ty::ty_fn_ret(method_ty).unwrap();
-                    Ok(self.cat_deref(expr,
-                                      self.cat_rvalue_node(expr.id(),
-                                                           expr.span(),
-                                                           ret_ty), 1, true))
+                    self.cat_deref(expr,
+                                   self.cat_rvalue_node(expr.id(),
+                                                        expr.span(),
+                                                        ret_ty), 1, true)
                 }
                 None => {
-                    let base_cmt = if_ok!(self.cat_expr(&**base));
-                    Ok(self.cat_index(expr, base_cmt))
+                    let base_cmt = self.cat_expr(&**base);
+                    self.cat_index(expr, base_cmt)
                 }
             }
           }
@@ -551,7 +538,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
           ast::ExprInlineAsm(..) | ast::ExprBox(..) |
           ast::ExprForLoop(..) => {
-            Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
+            self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
           }
 
           ast::ExprIfLet(..) => {
@@ -568,43 +555,43 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                    span: Span,
                    expr_ty: Ty<'tcx>,
                    def: def::Def)
-                   -> McResult<cmt<'tcx>> {
+                   -> cmt<'tcx> {
         debug!("cat_def: id={} expr={} def={}",
                id, expr_ty.repr(self.tcx()), def);
 
         match def {
           def::DefStruct(..) | def::DefVariant(..) | def::DefFn(..) |
           def::DefStaticMethod(..) | def::DefConst(..) => {
-                Ok(self.cat_rvalue_node(id, span, expr_ty))
+                self.cat_rvalue_node(id, span, expr_ty)
           }
           def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) |
           def::DefTrait(_) | def::DefTy(..) | def::DefPrimTy(_) |
           def::DefTyParam(..) | def::DefTyParamBinder(..) | def::DefRegion(_) |
           def::DefLabel(_) | def::DefSelfTy(..) | def::DefMethod(..) |
           def::DefAssociatedTy(..) | def::DefAssociatedPath(..)=> {
-              Ok(Rc::new(cmt_ {
+              Rc::new(cmt_ {
                   id:id,
                   span:span,
                   cat:cat_static_item,
                   mutbl: McImmutable,
                   ty:expr_ty,
                   note: NoteNone
-              }))
+              })
           }
 
           def::DefStatic(_, mutbl) => {
-              Ok(Rc::new(cmt_ {
+              Rc::new(cmt_ {
                   id:id,
                   span:span,
                   cat:cat_static_item,
                   mutbl: if mutbl { McDeclared } else { McImmutable},
                   ty:expr_ty,
                   note: NoteNone
-              }))
+              })
           }
 
           def::DefUpvar(var_id, fn_node_id, _) => {
-              let ty = if_ok!(self.node_ty(fn_node_id));
+              let ty = self.node_ty(fn_node_id);
               match ty.sty {
                   ty::ty_closure(ref closure_ty) => {
                       // Translate old closure type info into unboxed
@@ -642,14 +629,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           }
 
           def::DefLocal(vid) => {
-            Ok(Rc::new(cmt_ {
+            Rc::new(cmt_ {
                 id: id,
                 span: span,
                 cat: cat_local(vid),
                 mutbl: MutabilityCategory::from_local(self.tcx(), vid),
                 ty: expr_ty,
                 note: NoteNone
-            }))
+            })
           }
         }
     }
@@ -664,7 +651,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                  kind: ty::UnboxedClosureKind,
                  mode: ast::CaptureClause,
                  is_unboxed: bool)
-                 -> McResult<cmt<'tcx>> {
+                 -> cmt<'tcx> {
         // An upvar can have up to 3 components.  The base is a
         // `cat_upvar`.  Next, we add a deref through the implicit
         // environment pointer with an anonymous free region 'env and
@@ -686,7 +673,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         // FnOnce         | copied               | upvar -> &'up bk
         // old stack      | N/A                  | upvar -> &'env mut -> &'up bk
         // old proc/once  | copied               | N/A
-        let var_ty = if_ok!(self.node_ty(var_id));
+        let var_ty = self.node_ty(var_id);
 
         let upvar_id = ty::UpvarId { var_id: var_id,
                                      closure_expr_id: fn_node_id };
@@ -734,7 +721,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         });
 
         // First, switch by capture mode
-        Ok(match mode {
+        match mode {
             ast::CaptureByValue => {
                 let mut base = cmt_ {
                     id: id,
@@ -816,7 +803,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                     note: NoteUpvarRef(upvar_id)
                 })
             }
-        })
+        }
     }
 
     pub fn cat_rvalue_node(&self,
@@ -1065,13 +1052,13 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
     pub fn cat_slice_pattern(&self,
                              vec_cmt: cmt<'tcx>,
                              slice_pat: &ast::Pat)
-                             -> McResult<(cmt<'tcx>, ast::Mutability, ty::Region)> {
-        let slice_ty = if_ok!(self.node_ty(slice_pat.id));
+                             -> (cmt<'tcx>, ast::Mutability, ty::Region) {
+        let slice_ty = self.node_ty(slice_pat.id);
         let (slice_mutbl, slice_r) = vec_slice_info(self.tcx(),
                                                     slice_pat,
                                                     slice_ty);
         let cmt_slice = self.cat_index(slice_pat, self.deref_vec(slice_pat, vec_cmt));
-        return Ok((cmt_slice, slice_mutbl, slice_r));
+        return (cmt_slice, slice_mutbl, slice_r);
 
         /// In a pattern like [a, b, ..c], normally `c` has slice type, but if you have [a, b,
         /// ..ref c], then the type of `ref c` will be `&&[]`, so to extract the slice details we
@@ -1131,7 +1118,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                        cmt: cmt<'tcx>,
                        pat: &ast::Pat,
                        op: |&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat|)
-                       -> McResult<()> {
+    {
         // Here, `cmt` is the categorization for the value being
         // matched and pat is the pattern it is being matched against.
         //
@@ -1211,30 +1198,30 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                 Some(&def::DefVariant(..)) => {
                     // variant(x, y, z)
                     for (i, subpat) in subpats.iter().enumerate() {
-                        let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
+                        let subpat_ty = self.pat_ty(&**subpat); // see (*2)
 
                         let subcmt =
                             self.cat_imm_interior(
                                 pat, cmt.clone(), subpat_ty,
                                 InteriorField(PositionalField(i)));
 
-                        if_ok!(self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z)));
+                        self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z));
                     }
                 }
                 Some(&def::DefStruct(..)) => {
                     for (i, subpat) in subpats.iter().enumerate() {
-                        let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
+                        let subpat_ty = self.pat_ty(&**subpat); // see (*2)
                         let cmt_field =
                             self.cat_imm_interior(
                                 pat, cmt.clone(), subpat_ty,
                                 InteriorField(PositionalField(i)));
-                        if_ok!(self.cat_pattern(cmt_field, &**subpat,
-                                                |x,y,z| op(x,y,z)));
+                        self.cat_pattern(cmt_field, &**subpat,
+                                         |x,y,z| op(x,y,z));
                     }
                 }
                 Some(&def::DefConst(..)) => {
                     for subpat in subpats.iter() {
-                        if_ok!(self.cat_pattern(cmt.clone(), &**subpat, |x,y,z| op(x,y,z)));
+                        self.cat_pattern(cmt.clone(), &**subpat, |x,y,z| op(x,y,z));
                     }
                 }
                 _ => {
@@ -1246,7 +1233,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           }
 
           ast::PatIdent(_, _, Some(ref subpat)) => {
-              if_ok!(self.cat_pattern(cmt, &**subpat, op));
+              self.cat_pattern(cmt, &**subpat, op);
           }
 
           ast::PatIdent(_, _, None) => {
@@ -1256,43 +1243,43 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           ast::PatStruct(_, ref field_pats, _) => {
             // {f1: p1, ..., fN: pN}
             for fp in field_pats.iter() {
-                let field_ty = if_ok!(self.pat_ty(&*fp.node.pat)); // see (*2)
+                let field_ty = self.pat_ty(&*fp.node.pat); // see (*2)
                 let cmt_field = self.cat_field(pat, cmt.clone(), fp.node.ident.name, field_ty);
-                if_ok!(self.cat_pattern(cmt_field, &*fp.node.pat, |x,y,z| op(x,y,z)));
+                self.cat_pattern(cmt_field, &*fp.node.pat, |x,y,z| op(x,y,z));
             }
           }
 
           ast::PatTup(ref subpats) => {
             // (p1, ..., pN)
             for (i, subpat) in subpats.iter().enumerate() {
-                let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
+                let subpat_ty = self.pat_ty(&**subpat); // see (*2)
                 let subcmt =
                     self.cat_imm_interior(
                         pat, cmt.clone(), subpat_ty,
                         InteriorField(PositionalField(i)));
-                if_ok!(self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z)));
+                self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z));
             }
           }
 
           ast::PatBox(ref subpat) | ast::PatRegion(ref subpat) => {
             // @p1, ~p1, ref p1
             let subcmt = self.cat_deref(pat, cmt, 0, false);
-            if_ok!(self.cat_pattern(subcmt, &**subpat, op));
+            self.cat_pattern(subcmt, &**subpat, op);
           }
 
           ast::PatVec(ref before, ref slice, ref after) => {
               let elt_cmt = self.cat_index(pat, self.deref_vec(pat, cmt));
               for before_pat in before.iter() {
-                  if_ok!(self.cat_pattern(elt_cmt.clone(), &**before_pat,
-                                          |x,y,z| op(x,y,z)));
+                  self.cat_pattern(elt_cmt.clone(), &**before_pat,
+                                   |x,y,z| op(x,y,z));
               }
               for slice_pat in slice.iter() {
-                  let slice_ty = if_ok!(self.pat_ty(&**slice_pat));
+                  let slice_ty = self.pat_ty(&**slice_pat);
                   let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
-                  if_ok!(self.cat_pattern(slice_cmt, &**slice_pat, |x,y,z| op(x,y,z)));
+                  self.cat_pattern(slice_cmt, &**slice_pat, |x,y,z| op(x,y,z));
               }
               for after_pat in after.iter() {
-                  if_ok!(self.cat_pattern(elt_cmt.clone(), &**after_pat, |x,y,z| op(x,y,z)));
+                  self.cat_pattern(elt_cmt.clone(), &**after_pat, |x,y,z| op(x,y,z));
               }
           }
 
@@ -1304,8 +1291,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
               self.tcx().sess.span_bug(pat.span, "unexpanded macro");
           }
         }
-
-        Ok(())
     }
 
     pub fn cmt_to_string(&self, cmt: &cmt_<'tcx>) -> String {
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index f849f4c9b93..5ee6dec7830 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -1228,8 +1228,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             .iter()
                             .map(|freevar| {
                                 let freevar_def_id = freevar.def.def_id();
-                                self.typer.node_ty(freevar_def_id.node)
-                                    .unwrap_or(ty::mk_err()).subst(self.tcx(), substs)
+                                self.typer.node_ty(freevar_def_id.node).subst(self.tcx(), substs)
                             })
                             .collect();
                         Ok(If(tys))
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 659cf85937e..7add505e0eb 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -6165,12 +6165,12 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> {
         self
     }
 
-    fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
-        Ok(ty::node_id_to_type(self, id))
+    fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
+        ty::node_id_to_type(self, id)
     }
 
-    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
-        Ok(ty::expr_ty_adjusted(self, expr))
+    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
+        ty::expr_ty_adjusted(self, expr)
     }
 
     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index a13001b7968..b57b76d66f7 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -516,12 +516,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
     }
 
     pub fn cat_expr(&self, expr: &ast::Expr) -> mc::cmt<'tcx> {
-        match self.mc().cat_expr(expr) {
-            Ok(c) => c,
-            Err(()) => {
-                self.tcx.sess.span_bug(expr.span, "error in mem categorization");
-            }
-        }
+        self.mc().cat_expr(expr)
     }
 
     pub fn report(&self, err: BckError<'tcx>) {
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index 883205765f2..64ab9448795 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -463,12 +463,12 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
         self.tcx()
     }
 
-    fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
-        Ok(node_id_type(self, id))
+    fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
+        node_id_type(self, id)
     }
 
-    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
-        Ok(expr_ty_adjusted(self, expr))
+    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
+        expr_ty_adjusted(self, expr)
     }
 
     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index ca8c901b6fd..b046b39b283 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -86,7 +86,7 @@ use check::_match::pat_ctxt;
 use middle::{const_eval, def};
 use middle::infer;
 use middle::lang_items::IteratorItem;
-use middle::mem_categorization::{mod, McResult};
+use middle::mem_categorization as mc;
 use middle::pat_util::{mod, pat_id_map};
 use middle::region::CodeExtent;
 use middle::subst::{mod, Subst, Substs, VecPerParamSpace, ParamSpace};
@@ -282,24 +282,24 @@ pub struct FnCtxt<'a, 'tcx: 'a> {
     ccx: &'a CrateCtxt<'a, 'tcx>,
 }
 
-impl<'a, 'tcx> mem_categorization::Typer<'tcx> for FnCtxt<'a, 'tcx> {
+impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
     fn tcx(&self) -> &ty::ctxt<'tcx> {
         self.ccx.tcx
     }
-    fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
+    fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
         let ty = self.node_ty(id);
-        Ok(self.infcx().resolve_type_vars_if_possible(ty))
+        self.infcx().resolve_type_vars_if_possible(&ty)
     }
-    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
+    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
         let ty = self.expr_ty_adjusted(expr);
-        Ok(self.infcx().resolve_type_vars_if_possible(ty))
+        self.infcx().resolve_type_vars_if_possible(&ty)
     }
     fn node_method_ty(&self, method_call: ty::MethodCall)
                       -> Option<Ty<'tcx>> {
         self.inh.method_map.borrow()
                            .get(&method_call)
                            .map(|method| method.ty)
-                           .map(|ty| self.infcx().resolve_type_vars_if_possible(ty))
+                           .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty))
     }
     fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
         &self.inh.adjustments
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index f2aeea665b6..429eee87026 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -193,19 +193,6 @@ pub fn regionck_ensure_component_tys_wf<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 ///////////////////////////////////////////////////////////////////////////
 // INTERNALS
 
-// If mem categorization results in an error, it's because the type
-// check failed (or will fail, when the error is uncovered and
-// reported during writeback). In this case, we just ignore this part
-// of the code and don't try to add any more region constraints.
-macro_rules! ignore_err {
-    ($inp: expr) => (
-        match $inp {
-            Ok(v) => v,
-            Err(()) => return
-        }
-    )
-}
-
 // Stores parameters for a potential call to link_region()
 // to perform if an upvar reference is marked unique/mutable after
 // it has already been processed before.
@@ -1040,7 +1027,7 @@ fn constrain_callee(rcx: &mut Rcx,
                     // While we're here, link the closure's region with a unique
                     // immutable borrow (gathered later in borrowck)
                     let mc = mc::MemCategorizationContext::new(rcx.fcx);
-                    let expr_cmt = ignore_err!(mc.cat_expr(callee_expr));
+                    let expr_cmt = mc.cat_expr(callee_expr);
                     link_region(rcx, callee_expr.span, call_region,
                                 ty::UniqueImmBorrow, expr_cmt);
                     r
@@ -1149,7 +1136,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                 };
                 {
                     let mc = mc::MemCategorizationContext::new(rcx.fcx);
-                    let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i));
+                    let self_cmt = mc.cat_expr_autoderefd(deref_expr, i);
                     link_region(rcx, deref_expr.span, r,
                                 ty::BorrowKind::from_mutbl(m), self_cmt);
                 }
@@ -1245,7 +1232,7 @@ fn link_addr_of(rcx: &mut Rcx, expr: &ast::Expr,
 
     let cmt = {
         let mc = mc::MemCategorizationContext::new(rcx.fcx);
-        ignore_err!(mc.cat_expr(base))
+        mc.cat_expr(base)
     };
     link_region_from_node_type(rcx, expr.span, expr.id, mutability, cmt);
 }
@@ -1260,7 +1247,7 @@ fn link_local(rcx: &Rcx, local: &ast::Local) {
         Some(ref expr) => &**expr,
     };
     let mc = mc::MemCategorizationContext::new(rcx.fcx);
-    let discr_cmt = ignore_err!(mc.cat_expr(init_expr));
+    let discr_cmt = mc.cat_expr(init_expr);
     link_pattern(rcx, mc, discr_cmt, &*local.pat);
 }
 
@@ -1270,7 +1257,7 @@ fn link_local(rcx: &Rcx, local: &ast::Local) {
 fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) {
     debug!("regionck::for_match()");
     let mc = mc::MemCategorizationContext::new(rcx.fcx);
-    let discr_cmt = ignore_err!(mc.cat_expr(discr));
+    let discr_cmt = mc.cat_expr(discr);
     debug!("discr_cmt={}", discr_cmt.repr(rcx.tcx()));
     for arm in arms.iter() {
         for root_pat in arm.pats.iter() {
@@ -1316,14 +1303,11 @@ fn link_pattern<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
 
                 // `[_, ..slice, _]` pattern
                 ast::PatVec(_, Some(ref slice_pat), _) => {
-                    match mc.cat_slice_pattern(sub_cmt, &**slice_pat) {
-                        Ok((slice_cmt, slice_mutbl, slice_r)) => {
-                            link_region(rcx, sub_pat.span, slice_r,
-                                        ty::BorrowKind::from_mutbl(slice_mutbl),
-                                        slice_cmt);
-                        }
-                        Err(()) => {}
-                    }
+                    let (slice_cmt, slice_mutbl, slice_r) =
+                        mc.cat_slice_pattern(sub_cmt, &**slice_pat);
+                    link_region(rcx, sub_pat.span, slice_r,
+                                ty::BorrowKind::from_mutbl(slice_mutbl),
+                                slice_cmt);
                 }
                 _ => {}
             }
@@ -1339,7 +1323,7 @@ fn link_autoref(rcx: &Rcx,
 
     debug!("link_autoref(autoref={})", autoref);
     let mc = mc::MemCategorizationContext::new(rcx.fcx);
-    let expr_cmt = ignore_err!(mc.cat_expr_autoderefd(expr, autoderefs));
+    let expr_cmt = mc.cat_expr_autoderefd(expr, autoderefs);
     debug!("expr_cmt={}", expr_cmt.repr(rcx.tcx()));
 
     match *autoref {
@@ -1361,7 +1345,7 @@ fn link_by_ref(rcx: &Rcx,
     debug!("link_by_ref(expr={}, callee_scope={})",
            expr.repr(tcx), callee_scope);
     let mc = mc::MemCategorizationContext::new(rcx.fcx);
-    let expr_cmt = ignore_err!(mc.cat_expr(expr));
+    let expr_cmt = mc.cat_expr(expr);
     let borrow_region = ty::ReScope(callee_scope);
     link_region(rcx, expr.span, borrow_region, ty::ImmBorrow, expr_cmt);
 }
@@ -1629,7 +1613,7 @@ fn link_reborrowed_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
 fn adjust_borrow_kind_for_assignment_lhs(rcx: &Rcx,
                                          lhs: &ast::Expr) {
     let mc = mc::MemCategorizationContext::new(rcx.fcx);
-    let cmt = ignore_err!(mc.cat_expr(lhs));
+    let cmt = mc.cat_expr(lhs);
     adjust_upvar_borrow_kind_for_mut(rcx, cmt);
 }