about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-06 20:04:18 +0000
committerbors <bors@rust-lang.org>2018-10-06 20:04:18 +0000
commit4efdc04a5d687fce7a63ca339e5c74d8c51e40d2 (patch)
tree5acf43273b4911032b0951612a32b7be894e98e2
parent7ec50f4659ae112a16381bc916466e12aaf7b044 (diff)
parent786b86ef5d8d55957f70f51e98003a9ac0ea0405 (diff)
downloadrust-4efdc04a5d687fce7a63ca339e5c74d8c51e40d2.tar.gz
rust-4efdc04a5d687fce7a63ca339e5c74d8c51e40d2.zip
Auto merge of #54756 - ljedrz:cleanup_middle, r=michaelwoerister
Cleanup rustc/middle

- improve allocations
- use `Cow<'static, str>` where applicable
- improve some patterns
- whitespace & formatting fixes
-rw-r--r--src/librustc/middle/dead.rs12
-rw-r--r--src/librustc/middle/dependency_format.rs6
-rw-r--r--src/librustc/middle/entry.rs10
-rw-r--r--src/librustc/middle/exported_symbols.rs8
-rw-r--r--src/librustc/middle/expr_use_visitor.rs25
-rw-r--r--src/librustc/middle/intrinsicck.rs4
-rw-r--r--src/librustc/middle/lang_items.rs13
-rw-r--r--src/librustc/middle/lib_features.rs4
-rw-r--r--src/librustc/middle/liveness.rs560
-rw-r--r--src/librustc/middle/mem_categorization.rs477
-rw-r--r--src/librustc/middle/reachable.rs5
-rw-r--r--src/librustc/middle/region.rs34
-rw-r--r--src/librustc/middle/resolve_lifetime.rs131
-rw-r--r--src/librustc/middle/stability.rs28
-rw-r--r--src/librustc/middle/weak_lang_items.rs6
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs29
16 files changed, 641 insertions, 711 deletions
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 66305ae8836..2a157a9ff68 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -131,12 +131,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn mark_live_symbols(&mut self) {
         let mut scanned = FxHashSet();
-        while !self.worklist.is_empty() {
-            let id = self.worklist.pop().unwrap();
-            if scanned.contains(&id) {
+        while let Some(id) = self.worklist.pop() {
+            if !scanned.insert(id) {
                 continue
             }
-            scanned.insert(id);
 
             if let Some(ref node) = self.tcx.hir.find(id) {
                 self.live_symbols.insert(id);
@@ -212,7 +210,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
     }
 
     fn visit_variant_data(&mut self, def: &'tcx hir::VariantData, _: ast::Name,
-                        _: &hir::Generics, _: ast::NodeId, _: syntax_pos::Span) {
+                          _: &hir::Generics, _: ast::NodeId, _: syntax_pos::Span) {
         let has_repr_c = self.repr_has_repr_c;
         let inherited_pub_visibility = self.inherited_pub_visibility;
         let live_fields = def.fields().iter().filter(|f| {
@@ -494,8 +492,8 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
                       ctor_id: Option<ast::NodeId>)
                       -> bool {
         if self.live_symbols.contains(&id)
-           || ctor_id.map_or(false,
-                             |ctor| self.live_symbols.contains(&ctor)) {
+           || ctor_id.map_or(false, |ctor| self.live_symbols.contains(&ctor))
+        {
             return true;
         }
         // If it's a type whose items are live, then it's live, too.
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 14551261819..95fb35165e7 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -163,7 +163,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 let src = tcx.used_crate_source(cnum);
                 if src.rlib.is_some() { continue }
                 sess.err(&format!("crate `{}` required to be available in rlib format, \
-                                  but was not found in this form",
+                                   but was not found in this form",
                                   tcx.crate_name(cnum)));
             }
             return Vec::new();
@@ -247,13 +247,13 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     _ => "dylib",
                 };
                 sess.err(&format!("crate `{}` required to be available in {} format, \
-                                  but was not found in this form",
+                                   but was not found in this form",
                                   tcx.crate_name(cnum), kind));
             }
         }
     }
 
-    return ret;
+    ret
 }
 
 fn add_library(tcx: TyCtxt<'_, '_, '_>,
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index b06d881bcae..93fe607f5fa 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 use hir::map as hir_map;
 use hir::def_id::{CRATE_DEF_INDEX};
 use session::{config, Session};
@@ -131,7 +130,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
                 ctxt.attr_main_fn = Some((item.id, item.span));
             } else {
                 struct_span_err!(ctxt.session, item.span, E0137,
-                          "multiple functions with a #[main] attribute")
+                                 "multiple functions with a #[main] attribute")
                 .span_label(item.span, "additional #[main] function")
                 .span_label(ctxt.attr_main_fn.unwrap().1, "first #[main] function")
                 .emit();
@@ -141,11 +140,8 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
             if ctxt.start_fn.is_none() {
                 ctxt.start_fn = Some((item.id, item.span));
             } else {
-                struct_span_err!(
-                    ctxt.session, item.span, E0138,
-                    "multiple 'start' functions")
-                    .span_label(ctxt.start_fn.unwrap().1,
-                                "previous `start` function here")
+                struct_span_err!(ctxt.session, item.span, E0138, "multiple 'start' functions")
+                    .span_label(ctxt.start_fn.unwrap().1, "previous `start` function here")
                     .span_label(item.span, "multiple `start` functions")
                     .emit();
             }
diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs
index 6a254f1a189..44572a1977a 100644
--- a/src/librustc/middle/exported_symbols.rs
+++ b/src/librustc/middle/exported_symbols.rs
@@ -35,12 +35,8 @@ impl_stable_hash_for!(enum self::SymbolExportLevel {
 
 impl SymbolExportLevel {
     pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
-        if threshold == SymbolExportLevel::Rust {
-            // We export everything from Rust dylibs
-            true
-        } else {
-            self == SymbolExportLevel::C
-        }
+        threshold == SymbolExportLevel::Rust // export everything from Rust dylibs
+          || self == SymbolExportLevel::C
     }
 }
 
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 1a86dc4027e..d6b43ffe6da 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -321,7 +321,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
                     region::Scope {
                         id: body.value.hir_id.local_id,
                         data: region::ScopeData::Node
-                    }));
+                }));
             let arg_cmt = Rc::new(self.mc.cat_rvalue(
                 arg.hir_id,
                 arg.pat.span,
@@ -402,20 +402,20 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
                 self.walk_expr(&subexpr)
             }
 
-            hir::ExprKind::Unary(hir::UnDeref, ref base) => {      // *base
+            hir::ExprKind::Unary(hir::UnDeref, ref base) => { // *base
                 self.select_from_expr(&base);
             }
 
-            hir::ExprKind::Field(ref base, _) => {         // base.f
+            hir::ExprKind::Field(ref base, _) => { // base.f
                 self.select_from_expr(&base);
             }
 
-            hir::ExprKind::Index(ref lhs, ref rhs) => {       // lhs[rhs]
+            hir::ExprKind::Index(ref lhs, ref rhs) => { // lhs[rhs]
                 self.select_from_expr(&lhs);
                 self.consume_expr(&rhs);
             }
 
-            hir::ExprKind::Call(ref callee, ref args) => {    // callee(args)
+            hir::ExprKind::Call(ref callee, ref args) => { // callee(args)
                 self.walk_callee(expr, &callee);
                 self.consume_exprs(args);
             }
@@ -801,10 +801,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             self.walk_pat(discr_cmt.clone(), &pat, mode);
         }
 
-        if let Some(ref guard) = arm.guard {
-            match guard {
-                hir::Guard::If(ref e) => self.consume_expr(e),
-            }
+        if let Some(hir::Guard::If(ref e)) = arm.guard {
+            self.consume_expr(e)
         }
 
         self.consume_expr(&arm.body);
@@ -826,12 +824,13 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
                                cmt_discr: mc::cmt<'tcx>,
                                pat: &hir::Pat,
                                mode: &mut TrackMatchMode) {
-        debug!("determine_pat_move_mode cmt_discr={:?} pat={:?}", cmt_discr,
-               pat);
+        debug!("determine_pat_move_mode cmt_discr={:?} pat={:?}", cmt_discr, pat);
+
         return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |cmt_pat, pat| {
             if let PatKind::Binding(..) = pat.node {
-                let bm = *self.mc.tables.pat_binding_modes().get(pat.hir_id)
-                                                          .expect("missing binding mode");
+                let bm = *self.mc.tables.pat_binding_modes()
+                                        .get(pat.hir_id)
+                                        .expect("missing binding mode");
                 match bm {
                     ty::BindByReference(..) =>
                         mode.lub(BorrowingMatch),
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index 8058f3dde66..9d54e798469 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -107,7 +107,7 @@ impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
                 }
                 Err(LayoutError::Unknown(bad)) => {
                     if bad == ty {
-                        "this type's size can vary".to_string()
+                        "this type's size can vary".to_owned()
                     } else {
                         format!("size can vary because of {}", bad)
                     }
@@ -117,7 +117,7 @@ impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
         };
 
         struct_span_err!(self.tcx.sess, span, E0512,
-            "transmute called with types of different sizes")
+                         "transmute called with types of different sizes")
             .note(&format!("source type: {} ({})", from, skeleton_string(from, sk_from)))
             .note(&format!("target type: {} ({})", to, skeleton_string(to, sk_to)))
             .emit();
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index ef70a4cc45d..0bd816b3e55 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -39,7 +39,6 @@ macro_rules! language_item_table {
         $( $variant:ident, $name:expr, $method:ident; )*
     ) => {
 
-
 enum_from_u32! {
     #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
     pub enum LangItem {
@@ -145,8 +144,8 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
 
     fn collect_item(&mut self, item_index: usize, item_def_id: DefId) {
         // Check for duplicates.
-        match self.items.items[item_index] {
-            Some(original_def_id) if original_def_id != item_def_id => {
+        if let Some(original_def_id) = self.items.items[item_index] {
+            if original_def_id != item_def_id {
                 let name = LangItem::from_u32(item_index as u32).unwrap().name();
                 let mut err = match self.tcx.hir.span_if_local(item_def_id) {
                     Some(span) => struct_span_err!(
@@ -161,17 +160,13 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
                             name)),
                 };
                 if let Some(span) = self.tcx.hir.span_if_local(original_def_id) {
-                    span_note!(&mut err, span,
-                               "first defined here.");
+                    span_note!(&mut err, span, "first defined here.");
                 } else {
                     err.note(&format!("first defined in crate `{}`.",
                                       self.tcx.crate_name(original_def_id.krate)));
                 }
                 err.emit();
             }
-            _ => {
-                // OK.
-            }
         }
 
         // Matched.
@@ -194,7 +189,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
         }
     }
 
-    return None;
+    None
 }
 
 pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems {
diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs
index ec618de6773..6055a05158f 100644
--- a/src/librustc/middle/lib_features.rs
+++ b/src/librustc/middle/lib_features.rs
@@ -128,8 +128,8 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> {
                 let msg = format!(
                     "feature `{}` is declared {}, but was previously declared {}",
                     feature,
-                    if since.is_some() { "stable"} else { "unstable" },
-                    if since.is_none() { "stable"} else { "unstable" },
+                    if since.is_some() { "stable" } else { "unstable" },
+                    if since.is_none() { "stable" } else { "unstable" },
                 );
                 self.tcx.sess.struct_span_err_with_code(span, &msg,
                     DiagnosticId::Error("E0711".into())).emit();
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index ff4b1fc2921..1b258a23462 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -170,7 +170,7 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_, '_, '_>) -> Strin
         VarDefNode(s) => {
             format!("Var def node [{}]", cm.span_to_string(s))
         }
-        ExitNode => "Exit node".to_string(),
+        ExitNode => "Exit node".to_owned(),
     }
 }
 
@@ -257,7 +257,6 @@ enum VarKind {
 
 struct IrMaps<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-
     num_live_nodes: usize,
     num_vars: usize,
     live_node_map: HirIdMap<LiveNode>,
@@ -330,7 +329,7 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
             Local(LocalInfo { name, .. }) | Arg(_, name) => {
                 name.to_string()
             },
-            CleanExit => "<clean-exit>".to_string()
+            CleanExit => "<clean-exit>".to_owned()
         }
     }
 
@@ -474,13 +473,15 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
         // construction site.
         let mut call_caps = Vec::new();
         ir.tcx.with_freevars(expr.id, |freevars| {
-            for fv in freevars {
+            call_caps.extend(freevars.iter().filter_map(|fv| {
                 if let Def::Local(rv) = fv.def {
                     let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
                     let var_hid = ir.tcx.hir.node_to_hir_id(rv);
-                    call_caps.push(CaptureInfo { ln: fv_ln, var_hid });
+                    Some(CaptureInfo { ln: fv_ln, var_hid })
+                } else {
+                    None
                 }
-            }
+            }));
         });
         ir.set_captures(expr.id, call_caps);
 
@@ -918,8 +919,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         self.rwu_table.assign_unpacked(idx, rwu);
     }
 
-    // _______________________________________________________________________
-
     fn compute(&mut self, body: &hir::Expr) -> LiveNode {
         // if there is a `break` or `again` at the top level, then it's
         // effectively a return---this only occurs in `for` loops,
@@ -941,10 +940,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         let entry_ln = self.propagate_through_expr(body, s.fallthrough_ln);
 
         // hack to skip the loop unless debug! is enabled:
-        debug!("^^ liveness computation results for body {} (entry={:?})",
-               {
+        debug!("^^ liveness computation results for body {} (entry={:?})", {
                    for ln_idx in 0..self.ir.num_live_nodes {
-                       debug!("{:?}", self.ln_str(LiveNode(ln_idx as u32)));
+                        debug!("{:?}", self.ln_str(LiveNode(ln_idx as u32)));
                    }
                    body.id
                },
@@ -1026,241 +1024,232 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         debug!("propagate_through_expr: {}", self.ir.tcx.hir.node_to_pretty_string(expr.id));
 
         match expr.node {
-          // Interesting cases with control flow or which gen/kill
-          hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
-              self.access_path(expr.hir_id, path, succ, ACC_READ | ACC_USE)
-          }
+            // Interesting cases with control flow or which gen/kill
+            hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
+                self.access_path(expr.hir_id, path, succ, ACC_READ | ACC_USE)
+            }
 
-          hir::ExprKind::Field(ref e, _) => {
-              self.propagate_through_expr(&e, succ)
-          }
+            hir::ExprKind::Field(ref e, _) => {
+                self.propagate_through_expr(&e, succ)
+            }
 
-          hir::ExprKind::Closure(.., blk_id, _, _) => {
-              debug!("{} is an ExprKind::Closure", self.ir.tcx.hir.node_to_pretty_string(expr.id));
-
-              // The next-node for a break is the successor of the entire
-              // loop. The next-node for a continue is the top of this loop.
-              let node = self.live_node(expr.hir_id, expr.span);
-
-              let break_ln = succ;
-              let cont_ln = node;
-              self.break_ln.insert(blk_id.node_id, break_ln);
-              self.cont_ln.insert(blk_id.node_id, cont_ln);
-
-              // the construction of a closure itself is not important,
-              // but we have to consider the closed over variables.
-              let caps = match self.ir.capture_info_map.get(&expr.id) {
-                  Some(caps) => caps.clone(),
-                  None => {
-                      span_bug!(expr.span, "no registered caps");
-                  }
-              };
-              caps.iter().rev().fold(succ, |succ, cap| {
-                  self.init_from_succ(cap.ln, succ);
-                  let var = self.variable(cap.var_hid, expr.span);
-                  self.acc(cap.ln, var, ACC_READ | ACC_USE);
-                  cap.ln
-              })
-          }
+            hir::ExprKind::Closure(.., blk_id, _, _) => {
+                debug!("{} is an ExprKind::Closure",
+                       self.ir.tcx.hir.node_to_pretty_string(expr.id));
+
+                // The next-node for a break is the successor of the entire
+                // loop. The next-node for a continue is the top of this loop.
+                let node = self.live_node(expr.hir_id, expr.span);
+
+                let break_ln = succ;
+                let cont_ln = node;
+                self.break_ln.insert(blk_id.node_id, break_ln);
+                self.cont_ln.insert(blk_id.node_id, cont_ln);
+
+                // the construction of a closure itself is not important,
+                // but we have to consider the closed over variables.
+                let caps = self.ir.capture_info_map.get(&expr.id).cloned().unwrap_or_else(||
+                    span_bug!(expr.span, "no registered caps"));
+
+                caps.iter().rev().fold(succ, |succ, cap| {
+                    self.init_from_succ(cap.ln, succ);
+                    let var = self.variable(cap.var_hid, expr.span);
+                    self.acc(cap.ln, var, ACC_READ | ACC_USE);
+                    cap.ln
+                })
+            }
 
-          hir::ExprKind::If(ref cond, ref then, ref els) => {
-            //
-            //     (cond)
-            //       |
-            //       v
-            //     (expr)
-            //     /   \
-            //    |     |
-            //    v     v
-            //  (then)(els)
-            //    |     |
-            //    v     v
-            //   (  succ  )
-            //
-            let else_ln = self.propagate_through_opt_expr(els.as_ref().map(|e| &**e), succ);
-            let then_ln = self.propagate_through_expr(&then, succ);
-            let ln = self.live_node(expr.hir_id, expr.span);
-            self.init_from_succ(ln, else_ln);
-            self.merge_from_succ(ln, then_ln, false);
-            self.propagate_through_expr(&cond, ln)
-          }
+            hir::ExprKind::If(ref cond, ref then, ref els) => {
+                //
+                //     (cond)
+                //       |
+                //       v
+                //     (expr)
+                //     /   \
+                //    |     |
+                //    v     v
+                //  (then)(els)
+                //    |     |
+                //    v     v
+                //   (  succ  )
+                //
+                let else_ln = self.propagate_through_opt_expr(els.as_ref().map(|e| &**e), succ);
+                let then_ln = self.propagate_through_expr(&then, succ);
+                let ln = self.live_node(expr.hir_id, expr.span);
+                self.init_from_succ(ln, else_ln);
+                self.merge_from_succ(ln, then_ln, false);
+                self.propagate_through_expr(&cond, ln)
+            }
 
-          hir::ExprKind::While(ref cond, ref blk, _) => {
-            self.propagate_through_loop(expr, WhileLoop(&cond), &blk, succ)
-          }
+            hir::ExprKind::While(ref cond, ref blk, _) => {
+                self.propagate_through_loop(expr, WhileLoop(&cond), &blk, succ)
+            }
 
-          // Note that labels have been resolved, so we don't need to look
-          // at the label ident
-          hir::ExprKind::Loop(ref blk, _, _) => {
-            self.propagate_through_loop(expr, LoopLoop, &blk, succ)
-          }
+            // Note that labels have been resolved, so we don't need to look
+            // at the label ident
+            hir::ExprKind::Loop(ref blk, _, _) => {
+                self.propagate_through_loop(expr, LoopLoop, &blk, succ)
+            }
 
-          hir::ExprKind::Match(ref e, ref arms, _) => {
-            //
-            //      (e)
-            //       |
-            //       v
-            //     (expr)
-            //     / | \
-            //    |  |  |
-            //    v  v  v
-            //   (..arms..)
-            //    |  |  |
-            //    v  v  v
-            //   (  succ  )
-            //
-            //
-            let ln = self.live_node(expr.hir_id, expr.span);
-            self.init_empty(ln, succ);
-            let mut first_merge = true;
-            for arm in arms {
-                let body_succ =
-                    self.propagate_through_expr(&arm.body, succ);
-                let guard_succ =
-                    self.propagate_through_opt_expr(
-                        arm.guard.as_ref().map(|g|
-                            match g {
-                                hir::Guard::If(e) => &**e,
-                            }),
-                        body_succ);
-                // only consider the first pattern; any later patterns must have
-                // the same bindings, and we also consider the first pattern to be
-                // the "authoritative" set of ids
-                let arm_succ =
-                    self.define_bindings_in_arm_pats(arm.pats.first().map(|p| &**p),
-                                                     guard_succ);
-                self.merge_from_succ(ln, arm_succ, first_merge);
-                first_merge = false;
-            };
-            self.propagate_through_expr(&e, ln)
-          }
+            hir::ExprKind::Match(ref e, ref arms, _) => {
+                //
+                //      (e)
+                //       |
+                //       v
+                //     (expr)
+                //     / | \
+                //    |  |  |
+                //    v  v  v
+                //   (..arms..)
+                //    |  |  |
+                //    v  v  v
+                //   (  succ  )
+                //
+                //
+                let ln = self.live_node(expr.hir_id, expr.span);
+                self.init_empty(ln, succ);
+                let mut first_merge = true;
+                for arm in arms {
+                    let body_succ = self.propagate_through_expr(&arm.body, succ);
+
+                    let guard_succ = self.propagate_through_opt_expr(
+                        arm.guard.as_ref().map(|hir::Guard::If(e)| &**e),
+                        body_succ
+                    );
+                    // only consider the first pattern; any later patterns must have
+                    // the same bindings, and we also consider the first pattern to be
+                    // the "authoritative" set of ids
+                    let arm_succ =
+                        self.define_bindings_in_arm_pats(arm.pats.first().map(|p| &**p),
+                                                         guard_succ);
+                    self.merge_from_succ(ln, arm_succ, first_merge);
+                    first_merge = false;
+                };
+                self.propagate_through_expr(&e, ln)
+            }
 
-          hir::ExprKind::Ret(ref o_e) => {
-            // ignore succ and subst exit_ln:
-            let exit_ln = self.s.exit_ln;
-            self.propagate_through_opt_expr(o_e.as_ref().map(|e| &**e), exit_ln)
-          }
+            hir::ExprKind::Ret(ref o_e) => {
+                // ignore succ and subst exit_ln:
+                let exit_ln = self.s.exit_ln;
+                self.propagate_through_opt_expr(o_e.as_ref().map(|e| &**e), exit_ln)
+            }
 
-          hir::ExprKind::Break(label, ref opt_expr) => {
-              // Find which label this break jumps to
-              let target = match label.target_id {
+            hir::ExprKind::Break(label, ref opt_expr) => {
+                // Find which label this break jumps to
+                let target = match label.target_id {
                     Ok(node_id) => self.break_ln.get(&node_id),
                     Err(err) => span_bug!(expr.span, "loop scope error: {}", err),
-              }.map(|x| *x);
-
-              // Now that we know the label we're going to,
-              // look it up in the break loop nodes table
+                }.cloned();
 
-              match target {
-                  Some(b) => self.propagate_through_opt_expr(opt_expr.as_ref().map(|e| &**e), b),
-                  None => span_bug!(expr.span, "break to unknown label")
-              }
-          }
+                // Now that we know the label we're going to,
+                // look it up in the break loop nodes table
 
-          hir::ExprKind::Continue(label) => {
-              // Find which label this expr continues to
-              let sc = match label.target_id {
-                    Ok(node_id) => node_id,
-                    Err(err) => span_bug!(expr.span, "loop scope error: {}", err),
-              };
+                match target {
+                    Some(b) => self.propagate_through_opt_expr(opt_expr.as_ref().map(|e| &**e), b),
+                    None => span_bug!(expr.span, "break to unknown label")
+                }
+            }
 
-              // Now that we know the label we're going to,
-              // look it up in the continue loop nodes table
+            hir::ExprKind::Continue(label) => {
+                // Find which label this expr continues to
+                let sc = label.target_id.unwrap_or_else(|err|
+                    span_bug!(expr.span, "loop scope error: {}", err));
 
-              match self.cont_ln.get(&sc) {
-                  Some(&b) => b,
-                  None => span_bug!(expr.span, "continue to unknown label")
-              }
-          }
-
-          hir::ExprKind::Assign(ref l, ref r) => {
-            // see comment on places in
-            // propagate_through_place_components()
-            let succ = self.write_place(&l, succ, ACC_WRITE);
-            let succ = self.propagate_through_place_components(&l, succ);
-            self.propagate_through_expr(&r, succ)
-          }
+                // Now that we know the label we're going to,
+                // look it up in the continue loop nodes table
+                self.cont_ln.get(&sc).cloned().unwrap_or_else(||
+                    span_bug!(expr.span, "continue to unknown label"))
+            }
 
-          hir::ExprKind::AssignOp(_, ref l, ref r) => {
-            // an overloaded assign op is like a method call
-            if self.tables.is_method_call(expr) {
-                let succ = self.propagate_through_expr(&l, succ);
-                self.propagate_through_expr(&r, succ)
-            } else {
+            hir::ExprKind::Assign(ref l, ref r) => {
                 // see comment on places in
                 // propagate_through_place_components()
-                let succ = self.write_place(&l, succ, ACC_WRITE|ACC_READ);
-                let succ = self.propagate_through_expr(&r, succ);
-                self.propagate_through_place_components(&l, succ)
+                let succ = self.write_place(&l, succ, ACC_WRITE);
+                let succ = self.propagate_through_place_components(&l, succ);
+                self.propagate_through_expr(&r, succ)
             }
-          }
 
-          // Uninteresting cases: just propagate in rev exec order
+            hir::ExprKind::AssignOp(_, ref l, ref r) => {
+                // an overloaded assign op is like a method call
+                if self.tables.is_method_call(expr) {
+                    let succ = self.propagate_through_expr(&l, succ);
+                    self.propagate_through_expr(&r, succ)
+                } else {
+                    // see comment on places in
+                    // propagate_through_place_components()
+                    let succ = self.write_place(&l, succ, ACC_WRITE|ACC_READ);
+                    let succ = self.propagate_through_expr(&r, succ);
+                    self.propagate_through_place_components(&l, succ)
+                }
+            }
 
-          hir::ExprKind::Array(ref exprs) => {
-            self.propagate_through_exprs(exprs, succ)
-          }
+            // Uninteresting cases: just propagate in rev exec order
 
-          hir::ExprKind::Struct(_, ref fields, ref with_expr) => {
-            let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ);
-            fields.iter().rev().fold(succ, |succ, field| {
-                self.propagate_through_expr(&field.expr, succ)
-            })
-          }
+            hir::ExprKind::Array(ref exprs) => {
+                self.propagate_through_exprs(exprs, succ)
+            }
 
-          hir::ExprKind::Call(ref f, ref args) => {
-            // FIXME(canndrew): This is_never should really be an is_uninhabited
-            let succ = if self.tables.expr_ty(expr).is_never() {
-                self.s.exit_ln
-            } else {
-                succ
-            };
-            let succ = self.propagate_through_exprs(args, succ);
-            self.propagate_through_expr(&f, succ)
-          }
+            hir::ExprKind::Struct(_, ref fields, ref with_expr) => {
+                let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ);
+                fields.iter().rev().fold(succ, |succ, field| {
+                    self.propagate_through_expr(&field.expr, succ)
+                })
+            }
 
-          hir::ExprKind::MethodCall(.., ref args) => {
-            // FIXME(canndrew): This is_never should really be an is_uninhabited
-            let succ = if self.tables.expr_ty(expr).is_never() {
-                self.s.exit_ln
-            } else {
-                succ
-            };
-            self.propagate_through_exprs(args, succ)
-          }
+            hir::ExprKind::Call(ref f, ref args) => {
+                // FIXME(canndrew): This is_never should really be an is_uninhabited
+                let succ = if self.tables.expr_ty(expr).is_never() {
+                    self.s.exit_ln
+                } else {
+                    succ
+                };
+                let succ = self.propagate_through_exprs(args, succ);
+                self.propagate_through_expr(&f, succ)
+            }
 
-          hir::ExprKind::Tup(ref exprs) => {
-            self.propagate_through_exprs(exprs, succ)
-          }
+            hir::ExprKind::MethodCall(.., ref args) => {
+                // FIXME(canndrew): This is_never should really be an is_uninhabited
+                let succ = if self.tables.expr_ty(expr).is_never() {
+                    self.s.exit_ln
+                } else {
+                    succ
+                };
 
-          hir::ExprKind::Binary(op, ref l, ref r) if op.node.is_lazy() => {
-            let r_succ = self.propagate_through_expr(&r, succ);
+                self.propagate_through_exprs(args, succ)
+            }
 
-            let ln = self.live_node(expr.hir_id, expr.span);
-            self.init_from_succ(ln, succ);
-            self.merge_from_succ(ln, r_succ, false);
+            hir::ExprKind::Tup(ref exprs) => {
+                self.propagate_through_exprs(exprs, succ)
+            }
 
-            self.propagate_through_expr(&l, ln)
-          }
+            hir::ExprKind::Binary(op, ref l, ref r) if op.node.is_lazy() => {
+                let r_succ = self.propagate_through_expr(&r, succ);
 
-          hir::ExprKind::Index(ref l, ref r) |
-          hir::ExprKind::Binary(_, ref l, ref r) => {
-            let r_succ = self.propagate_through_expr(&r, succ);
-            self.propagate_through_expr(&l, r_succ)
-          }
+                let ln = self.live_node(expr.hir_id, expr.span);
+                self.init_from_succ(ln, succ);
+                self.merge_from_succ(ln, r_succ, false);
 
-          hir::ExprKind::Box(ref e) |
-          hir::ExprKind::AddrOf(_, ref e) |
-          hir::ExprKind::Cast(ref e, _) |
-          hir::ExprKind::Type(ref e, _) |
-          hir::ExprKind::Unary(_, ref e) |
-          hir::ExprKind::Yield(ref e) |
-          hir::ExprKind::Repeat(ref e, _) => {
-            self.propagate_through_expr(&e, succ)
-          }
+                self.propagate_through_expr(&l, ln)
+            }
+
+            hir::ExprKind::Index(ref l, ref r) |
+            hir::ExprKind::Binary(_, ref l, ref r) => {
+                let r_succ = self.propagate_through_expr(&r, succ);
+                self.propagate_through_expr(&l, r_succ)
+            }
+
+            hir::ExprKind::Box(ref e) |
+            hir::ExprKind::AddrOf(_, ref e) |
+            hir::ExprKind::Cast(ref e, _) |
+            hir::ExprKind::Type(ref e, _) |
+            hir::ExprKind::Unary(_, ref e) |
+            hir::ExprKind::Yield(ref e) |
+            hir::ExprKind::Repeat(ref e, _) => {
+                self.propagate_through_expr(&e, succ)
+            }
 
-          hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
-            let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
+            hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
+                let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
                 // see comment on places
                 // in propagate_through_place_components()
                 if o.is_indirect {
@@ -1269,29 +1258,28 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     let acc = if o.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
                     let succ = self.write_place(output, succ, acc);
                     self.propagate_through_place_components(output, succ)
-                }
-            });
+                }});
 
-            // Inputs are executed first. Propagate last because of rev order
-            self.propagate_through_exprs(inputs, succ)
-          }
+                // Inputs are executed first. Propagate last because of rev order
+                self.propagate_through_exprs(inputs, succ)
+            }
 
-          hir::ExprKind::Lit(..) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
-            succ
-          }
+            hir::ExprKind::Lit(..) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
+                succ
+            }
 
-          // Note that labels have been resolved, so we don't need to look
-          // at the label ident
-          hir::ExprKind::Block(ref blk, _) => {
-            self.propagate_through_block(&blk, succ)
-          }
+            // Note that labels have been resolved, so we don't need to look
+            // at the label ident
+            hir::ExprKind::Block(ref blk, _) => {
+                self.propagate_through_block(&blk, succ)
+            }
         }
     }
 
     fn propagate_through_place_components(&mut self,
-                                           expr: &Expr,
-                                           succ: LiveNode)
-                                           -> LiveNode {
+                                          expr: &Expr,
+                                          succ: LiveNode)
+                                          -> LiveNode {
         // # Places
         //
         // In general, the full flow graph structure for an
@@ -1349,18 +1337,17 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     // see comment on propagate_through_place()
-    fn write_place(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
-                    -> LiveNode {
+    fn write_place(&mut self, expr: &Expr, succ: LiveNode, acc: u32) -> LiveNode {
         match expr.node {
-          hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
-              self.access_path(expr.hir_id, path, succ, acc)
-          }
+            hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
+                self.access_path(expr.hir_id, path, succ, acc)
+            }
 
-          // We do not track other places, so just propagate through
-          // to their subcomponents.  Also, it may happen that
-          // non-places occur here, because those are detected in the
-          // later pass borrowck.
-          _ => succ
+            // We do not track other places, so just propagate through
+            // to their subcomponents.  Also, it may happen that
+            // non-places occur here, because those are detected in the
+            // later pass borrowck.
+            _ => succ
         }
     }
 
@@ -1379,10 +1366,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn access_path(&mut self, hir_id: HirId, path: &hir::Path, succ: LiveNode, acc: u32)
                    -> LiveNode {
         match path.def {
-          Def::Local(nid) => {
-            self.access_var(hir_id, nid, succ, acc, path.span)
-          }
-          _ => succ
+            Def::Local(nid) => {
+              self.access_var(hir_id, nid, succ, acc, path.span)
+            }
+            _ => succ
         }
     }
 
@@ -1392,7 +1379,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                               body: &hir::Block,
                               succ: LiveNode)
                               -> LiveNode {
-
         /*
 
         We model control flow like this:
@@ -1450,8 +1436,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     self.propagate_through_expr(&cond, ln)
                 }
             };
-            assert!(cond_ln == new_cond_ln);
-            assert!(body_ln == self.propagate_through_block(body, cond_ln));
+            assert_eq!(cond_ln, new_cond_ln);
+            assert_eq!(body_ln, self.propagate_through_block(body, cond_ln));
         }
 
         cond_ln
@@ -1505,49 +1491,49 @@ fn check_arm<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, arm: &'tcx hir::Arm) {
 
 fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
     match expr.node {
-      hir::ExprKind::Assign(ref l, _) => {
-        this.check_place(&l);
-
-        intravisit::walk_expr(this, expr);
-      }
-
-      hir::ExprKind::AssignOp(_, ref l, _) => {
-        if !this.tables.is_method_call(expr) {
+        hir::ExprKind::Assign(ref l, _) => {
             this.check_place(&l);
+
+            intravisit::walk_expr(this, expr);
         }
 
-        intravisit::walk_expr(this, expr);
-      }
+        hir::ExprKind::AssignOp(_, ref l, _) => {
+            if !this.tables.is_method_call(expr) {
+                this.check_place(&l);
+            }
 
-      hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
-        for input in inputs {
-          this.visit_expr(input);
+            intravisit::walk_expr(this, expr);
         }
 
-        // Output operands must be places
-        for (o, output) in ia.outputs.iter().zip(outputs) {
-          if !o.is_indirect {
-            this.check_place(output);
-          }
-          this.visit_expr(output);
-        }
+        hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
+            for input in inputs {
+                this.visit_expr(input);
+            }
 
-        intravisit::walk_expr(this, expr);
-      }
+            // Output operands must be places
+            for (o, output) in ia.outputs.iter().zip(outputs) {
+                if !o.is_indirect {
+                    this.check_place(output);
+                }
+                this.visit_expr(output);
+            }
 
-      // no correctness conditions related to liveness
-      hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) | hir::ExprKind::If(..) |
-      hir::ExprKind::Match(..) | hir::ExprKind::While(..) | hir::ExprKind::Loop(..) |
-      hir::ExprKind::Index(..) | hir::ExprKind::Field(..) |
-      hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Binary(..) |
-      hir::ExprKind::Cast(..) | hir::ExprKind::Unary(..) | hir::ExprKind::Ret(..) |
-      hir::ExprKind::Break(..) | hir::ExprKind::Continue(..) | hir::ExprKind::Lit(_) |
-      hir::ExprKind::Block(..) | hir::ExprKind::AddrOf(..) |
-      hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
-      hir::ExprKind::Closure(..) | hir::ExprKind::Path(_) | hir::ExprKind::Yield(..) |
-      hir::ExprKind::Box(..) | hir::ExprKind::Type(..) => {
-        intravisit::walk_expr(this, expr);
-      }
+            intravisit::walk_expr(this, expr);
+        }
+
+        // no correctness conditions related to liveness
+        hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) | hir::ExprKind::If(..) |
+        hir::ExprKind::Match(..) | hir::ExprKind::While(..) | hir::ExprKind::Loop(..) |
+        hir::ExprKind::Index(..) | hir::ExprKind::Field(..) |
+        hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Binary(..) |
+        hir::ExprKind::Cast(..) | hir::ExprKind::Unary(..) | hir::ExprKind::Ret(..) |
+        hir::ExprKind::Break(..) | hir::ExprKind::Continue(..) | hir::ExprKind::Lit(_) |
+        hir::ExprKind::Block(..) | hir::ExprKind::AddrOf(..) |
+        hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
+        hir::ExprKind::Closure(..) | hir::ExprKind::Path(_) | hir::ExprKind::Yield(..) |
+        hir::ExprKind::Box(..) | hir::ExprKind::Type(..) => {
+            intravisit::walk_expr(this, expr);
+        }
     }
 }
 
@@ -1576,7 +1562,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
     fn should_warn(&self, var: Variable) -> Option<String> {
         let name = self.ir.variable_name(var);
-        if name.is_empty() || name.as_bytes()[0] == ('_' as u8) {
+        if name.is_empty() || name.as_bytes()[0] == b'_' {
             None
         } else {
             Some(name)
@@ -1617,7 +1603,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         if !self.used_on_entry(ln, var) {
             let r = self.should_warn(var);
             if let Some(name) = r {
-
                 // annoying: for parameters in funcs like `fn(x: i32)
                 // {ret}`, there is only one node, so asking about
                 // assigned_on_exit() is not meaningful.
@@ -1627,8 +1612,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     self.assigned_on_exit(ln, var).is_some()
                 };
 
-                let suggest_underscore_msg = format!("consider using `_{}` instead",
-                                                     name);
+                let suggest_underscore_msg = format!("consider using `_{}` instead", name);
 
                 if is_assigned {
                     self.ir.tcx
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 13c969cec29..13e6f7a4c74 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -83,6 +83,7 @@ use hir;
 use syntax::ast::{self, Name};
 use syntax_pos::Span;
 
+use std::borrow::Cow;
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use rustc_data_structures::sync::Lrc;
@@ -91,13 +92,13 @@ use util::nodemap::ItemLocalSet;
 
 #[derive(Clone, Debug, PartialEq)]
 pub enum Categorization<'tcx> {
-    Rvalue(ty::Region<'tcx>),              // temporary val, argument is its scope
+    Rvalue(ty::Region<'tcx>),            // temporary val, argument is its scope
     StaticItem,
-    Upvar(Upvar),                          // upvar referenced by closure env
-    Local(ast::NodeId),                    // local variable
+    Upvar(Upvar),                        // upvar referenced by closure env
+    Local(ast::NodeId),                  // local variable
     Deref(cmt<'tcx>, PointerKind<'tcx>), // deref of a ptr
-    Interior(cmt<'tcx>, InteriorKind),     // something interior: field, tuple, etc
-    Downcast(cmt<'tcx>, DefId),            // selects a particular enum variant (*1)
+    Interior(cmt<'tcx>, InteriorKind),   // something interior: field, tuple, etc
+    Downcast(cmt<'tcx>, DefId),          // selects a particular enum variant (*1)
 
     // (*1) downcast is only required if the enum has more than one variant
 }
@@ -149,8 +150,8 @@ impl Hash for FieldIndex {
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub enum InteriorOffsetKind {
-    Index,            // e.g. `array_expr[index_expr]`
-    Pattern,          // e.g. `fn foo([_, a, _, _]: [A; 4]) { ... }`
+    Index,   // e.g. `array_expr[index_expr]`
+    Pattern, // e.g. `fn foo([_, a, _, _]: [A; 4]) { ... }`
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
@@ -580,7 +581,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         fn helper<'a, 'gcx, 'tcx>(mc: &MemCategorizationContext<'a, 'gcx, 'tcx>,
                                   expr: &hir::Expr,
                                   adjustments: &[adjustment::Adjustment<'tcx>])
-                                   -> McResult<cmt_<'tcx>> {
+                                  -> McResult<cmt_<'tcx>> {
             match adjustments.split_last() {
                 None => mc.cat_expr_unadjusted(expr),
                 Some((adjustment, previous)) => {
@@ -640,61 +641,61 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
 
         let expr_ty = self.expr_ty(expr)?;
         match expr.node {
-          hir::ExprKind::Unary(hir::UnDeref, ref e_base) => {
-            if self.tables.is_method_call(expr) {
-                self.cat_overloaded_place(expr, e_base, NoteNone)
-            } else {
-                let base_cmt = Rc::new(self.cat_expr(&e_base)?);
-                self.cat_deref(expr, base_cmt, NoteNone)
+            hir::ExprKind::Unary(hir::UnDeref, ref e_base) => {
+                if self.tables.is_method_call(expr) {
+                    self.cat_overloaded_place(expr, e_base, NoteNone)
+                } else {
+                    let base_cmt = Rc::new(self.cat_expr(&e_base)?);
+                    self.cat_deref(expr, base_cmt, NoteNone)
+                }
             }
-          }
-
-          hir::ExprKind::Field(ref base, f_ident) => {
-            let base_cmt = Rc::new(self.cat_expr(&base)?);
-            debug!("cat_expr(cat_field): id={} expr={:?} base={:?}",
-                   expr.id,
-                   expr,
-                   base_cmt);
-            let f_index = self.tcx.field_index(expr.id, self.tables);
-            Ok(self.cat_field(expr, base_cmt, f_index, f_ident, expr_ty))
-          }
-
-          hir::ExprKind::Index(ref base, _) => {
-            if self.tables.is_method_call(expr) {
-                // If this is an index implemented by a method call, then it
-                // will include an implicit deref of the result.
-                // The call to index() returns a `&T` value, which
-                // is an rvalue. That is what we will be
-                // dereferencing.
-                self.cat_overloaded_place(expr, base, NoteIndex)
-            } else {
+
+            hir::ExprKind::Field(ref base, f_ident) => {
                 let base_cmt = Rc::new(self.cat_expr(&base)?);
-                self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
+                debug!("cat_expr(cat_field): id={} expr={:?} base={:?}",
+                       expr.id,
+                       expr,
+                       base_cmt);
+                let f_index = self.tcx.field_index(expr.id, self.tables);
+                Ok(self.cat_field(expr, base_cmt, f_index, f_ident, expr_ty))
+            }
+
+            hir::ExprKind::Index(ref base, _) => {
+                if self.tables.is_method_call(expr) {
+                    // If this is an index implemented by a method call, then it
+                    // will include an implicit deref of the result.
+                    // The call to index() returns a `&T` value, which
+                    // is an rvalue. That is what we will be
+                    // dereferencing.
+                    self.cat_overloaded_place(expr, base, NoteIndex)
+                } else {
+                    let base_cmt = Rc::new(self.cat_expr(&base)?);
+                    self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
+                }
+            }
+
+            hir::ExprKind::Path(ref qpath) => {
+                let def = self.tables.qpath_def(qpath, expr.hir_id);
+                self.cat_def(expr.hir_id, expr.span, expr_ty, def)
+            }
+
+            hir::ExprKind::Type(ref e, _) => {
+                self.cat_expr(&e)
+            }
+
+            hir::ExprKind::AddrOf(..) | hir::ExprKind::Call(..) |
+            hir::ExprKind::Assign(..) | hir::ExprKind::AssignOp(..) |
+            hir::ExprKind::Closure(..) | hir::ExprKind::Ret(..) |
+            hir::ExprKind::Unary(..) | hir::ExprKind::Yield(..) |
+            hir::ExprKind::MethodCall(..) | hir::ExprKind::Cast(..) |
+            hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::If(..) |
+            hir::ExprKind::Binary(..) | hir::ExprKind::While(..) |
+            hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) |
+            hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) |
+            hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
+            hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) => {
+                Ok(self.cat_rvalue_node(expr.hir_id, expr.span, expr_ty))
             }
-          }
-
-          hir::ExprKind::Path(ref qpath) => {
-              let def = self.tables.qpath_def(qpath, expr.hir_id);
-              self.cat_def(expr.hir_id, expr.span, expr_ty, def)
-          }
-
-          hir::ExprKind::Type(ref e, _) => {
-            self.cat_expr(&e)
-          }
-
-          hir::ExprKind::AddrOf(..) | hir::ExprKind::Call(..) |
-          hir::ExprKind::Assign(..) | hir::ExprKind::AssignOp(..) |
-          hir::ExprKind::Closure(..) | hir::ExprKind::Ret(..) |
-          hir::ExprKind::Unary(..) | hir::ExprKind::Yield(..) |
-          hir::ExprKind::MethodCall(..) | hir::ExprKind::Cast(..) |
-          hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::If(..) |
-          hir::ExprKind::Binary(..) | hir::ExprKind::While(..) |
-          hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) |
-          hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) |
-          hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
-          hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) => {
-            Ok(self.cat_rvalue_node(expr.hir_id, expr.span, expr_ty))
-          }
         }
     }
 
@@ -708,44 +709,45 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                hir_id, expr_ty, def);
 
         match def {
-          Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) |
-          Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) | Def::SelfCtor(..) => {
+            Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) |
+            Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) | Def::SelfCtor(..) => {
                 Ok(self.cat_rvalue_node(hir_id, span, expr_ty))
-          }
+            }
 
-          Def::Static(def_id, mutbl) => {
-            // `#[thread_local]` statics may not outlive the current function.
-            for attr in &self.tcx.get_attrs(def_id)[..] {
-                if attr.check_name("thread_local") {
-                    return Ok(self.cat_rvalue_node(hir_id, span, expr_ty));
+            Def::Static(def_id, mutbl) => {
+                // `#[thread_local]` statics may not outlive the current function.
+                for attr in &self.tcx.get_attrs(def_id)[..] {
+                    if attr.check_name("thread_local") {
+                        return Ok(self.cat_rvalue_node(hir_id, span, expr_ty));
+                    }
                 }
+
+                Ok(cmt_ {
+                    hir_id,
+                    span:span,
+                    cat:Categorization::StaticItem,
+                    mutbl: if mutbl { McDeclared } else { McImmutable},
+                    ty:expr_ty,
+                    note: NoteNone
+                })
+            }
+
+            Def::Upvar(var_id, _, fn_node_id) => {
+                self.cat_upvar(hir_id, span, var_id, fn_node_id)
             }
-              Ok(cmt_ {
-                  hir_id,
-                  span:span,
-                  cat:Categorization::StaticItem,
-                  mutbl: if mutbl { McDeclared } else { McImmutable},
-                  ty:expr_ty,
-                  note: NoteNone
-              })
-          }
-
-          Def::Upvar(var_id, _, fn_node_id) => {
-              self.cat_upvar(hir_id, span, var_id, fn_node_id)
-          }
-
-          Def::Local(vid) => {
-            Ok(cmt_ {
-                hir_id,
-                span,
-                cat: Categorization::Local(vid),
-                mutbl: MutabilityCategory::from_local(self.tcx, self.tables, vid),
-                ty: expr_ty,
-                note: NoteNone
-            })
-          }
 
-          def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def)
+            Def::Local(vid) => {
+                Ok(cmt_ {
+                    hir_id,
+                    span,
+                    cat: Categorization::Local(vid),
+                    mutbl: MutabilityCategory::from_local(self.tcx, self.tables, vid),
+                    ty: expr_ty,
+                    note: NoteNone
+                })
+            }
+
+            def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def)
         }
     }
 
@@ -941,19 +943,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                            span: Span,
                            expr_ty: Ty<'tcx>)
                            -> cmt_<'tcx> {
-        debug!(
-            "cat_rvalue_node(id={:?}, span={:?}, expr_ty={:?})",
-            hir_id,
-            span,
-            expr_ty,
-        );
+        debug!("cat_rvalue_node(id={:?}, span={:?}, expr_ty={:?})",
+               hir_id, span, expr_ty);
+
         let promotable = self.rvalue_promotable_map.as_ref().map(|m| m.contains(&hir_id.local_id))
                                                             .unwrap_or(false);
 
-        debug!(
-            "cat_rvalue_node: promotable = {:?}",
-            promotable,
-        );
+        debug!("cat_rvalue_node: promotable = {:?}", promotable);
 
         // Always promote `[T; 0]` (even when e.g. borrowed mutably).
         let promotable = match expr_ty.sty {
@@ -961,10 +957,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             _ => promotable,
         };
 
-        debug!(
-            "cat_rvalue_node: promotable = {:?} (2)",
-            promotable,
-        );
+        debug!("cat_rvalue_node: promotable = {:?} (2)", promotable);
 
         // Compute maximum lifetime of this rvalue. This is 'static if
         // we can promote to a constant, otherwise equal to enclosing temp
@@ -1022,12 +1015,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         base: &hir::Expr,
         note: Note,
     ) -> McResult<cmt_<'tcx>> {
-        debug!(
-            "cat_overloaded_place(expr={:?}, base={:?}, note={:?})",
-            expr,
-            base,
-            note,
-        );
+        debug!("cat_overloaded_place(expr={:?}, base={:?}, note={:?})",
+               expr,
+               base,
+               note);
 
         // Reconstruct the output assuming it's a reference with the
         // same region and mutability as the receiver. This holds for
@@ -1037,9 +1028,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
 
         let (region, mutbl) = match base_ty.sty {
             ty::Ref(region, _, mutbl) => (region, mutbl),
-            _ => {
-                span_bug!(expr.span, "cat_overloaded_place: base is not a reference")
-            }
+            _ => span_bug!(expr.span, "cat_overloaded_place: base is not a reference")
         };
         let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
             ty: place_ty,
@@ -1062,8 +1051,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         let deref_ty = match base_cmt_ty.builtin_deref(true) {
             Some(mt) => mt.ty,
             None => {
-                debug!("Explicit deref of non-derefable type: {:?}",
-                       base_cmt_ty);
+                debug!("Explicit deref of non-derefable type: {:?}", base_cmt_ty);
                 return Err(());
             }
         };
@@ -1120,11 +1108,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
     }
 
     pub fn cat_imm_interior<N:HirNode>(&self,
-                                        node: &N,
-                                        base_cmt: cmt<'tcx>,
-                                        interior_ty: Ty<'tcx>,
-                                        interior: InteriorKind)
-                                        -> cmt_<'tcx> {
+                                       node: &N,
+                                       base_cmt: cmt<'tcx>,
+                                       interior_ty: Ty<'tcx>,
+                                       interior: InteriorKind)
+                                       -> cmt_<'tcx> {
         let ret = cmt_ {
             hir_id: node.hir_id(),
             span: node.span(),
@@ -1138,10 +1126,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
     }
 
     pub fn cat_downcast_if_needed<N:HirNode>(&self,
-                                              node: &N,
-                                              base_cmt: cmt<'tcx>,
-                                              variant_did: DefId)
-                                              -> cmt<'tcx> {
+                                             node: &N,
+                                             base_cmt: cmt<'tcx>,
+                                             variant_did: DefId)
+                                             -> cmt<'tcx> {
         // univariant enums do not need downcasts
         let base_did = self.tcx.parent_def_id(variant_did).unwrap();
         if self.tcx.adt_def(base_did).variants.len() != 1 {
@@ -1277,117 +1265,120 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         op(cmt.clone(), pat);
 
         match pat.node {
-          PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
-            let def = self.tables.qpath_def(qpath, pat.hir_id);
-            let (cmt, expected_len) = match def {
-                Def::Err => {
-                    debug!("access to unresolvable pattern {:?}", pat);
-                    return Err(())
-                }
-                Def::VariantCtor(def_id, CtorKind::Fn) => {
-                    let enum_def = self.tcx.parent_def_id(def_id).unwrap();
-                    (self.cat_downcast_if_needed(pat, cmt, def_id),
-                     self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len())
-                }
-                Def::StructCtor(_, CtorKind::Fn) | Def::SelfCtor(..) => {
-                    match self.pat_ty_unadjusted(&pat)?.sty {
-                        ty::Adt(adt_def, _) => {
-                            (cmt, adt_def.non_enum_variant().fields.len())
-                        }
-                        ref ty => {
-                            span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty);
+            PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
+                let def = self.tables.qpath_def(qpath, pat.hir_id);
+                let (cmt, expected_len) = match def {
+                    Def::Err => {
+                        debug!("access to unresolvable pattern {:?}", pat);
+                        return Err(())
+                    }
+                    Def::VariantCtor(def_id, CtorKind::Fn) => {
+                        let enum_def = self.tcx.parent_def_id(def_id).unwrap();
+                        (self.cat_downcast_if_needed(pat, cmt, def_id),
+                        self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len())
+                    }
+                    Def::StructCtor(_, CtorKind::Fn) | Def::SelfCtor(..) => {
+                        match self.pat_ty_unadjusted(&pat)?.sty {
+                            ty::Adt(adt_def, _) => {
+                                (cmt, adt_def.non_enum_variant().fields.len())
+                            }
+                            ref ty => {
+                                span_bug!(pat.span,
+                                          "tuple struct pattern unexpected type {:?}", ty);
+                            }
                         }
                     }
+                    def => {
+                        span_bug!(pat.span, "tuple struct pattern didn't resolve \
+                                             to variant or struct {:?}", def);
+                    }
+                };
+
+                for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
+                    let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
+                    let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
+                    let subcmt = Rc::new(
+                        self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
+                    self.cat_pattern_(subcmt, &subpat, op)?;
                 }
-                def => {
-                    span_bug!(pat.span, "tuple struct pattern didn't resolve \
-                                         to variant or struct {:?}", def);
+            }
+
+            PatKind::Struct(ref qpath, ref field_pats, _) => {
+                // {f1: p1, ..., fN: pN}
+                let def = self.tables.qpath_def(qpath, pat.hir_id);
+                let cmt = match def {
+                    Def::Err => {
+                        debug!("access to unresolvable pattern {:?}", pat);
+                        return Err(())
+                    },
+                    Def::Variant(variant_did) |
+                    Def::VariantCtor(variant_did, ..) => {
+                        self.cat_downcast_if_needed(pat, cmt, variant_did)
+                    },
+                    _ => cmt
+                };
+
+                for fp in field_pats {
+                    let field_ty = self.pat_ty_adjusted(&fp.node.pat)?; // see (*2)
+                    let f_index = self.tcx.field_index(fp.node.id, self.tables);
+                    let cmt_field = Rc::new(self.cat_field(pat, cmt.clone(), f_index,
+                                                           fp.node.ident, field_ty));
+                    self.cat_pattern_(cmt_field, &fp.node.pat, op)?;
                 }
-            };
+            }
 
-            for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
-                let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
-                let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
-                let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
-                self.cat_pattern_(subcmt, &subpat, op)?;
+            PatKind::Binding(.., Some(ref subpat)) => {
+                self.cat_pattern_(cmt, &subpat, op)?;
             }
-          }
-
-          PatKind::Struct(ref qpath, ref field_pats, _) => {
-            // {f1: p1, ..., fN: pN}
-            let def = self.tables.qpath_def(qpath, pat.hir_id);
-            let cmt = match def {
-                Def::Err => {
-                    debug!("access to unresolvable pattern {:?}", pat);
-                    return Err(())
-                },
-                Def::Variant(variant_did) |
-                Def::VariantCtor(variant_did, ..) => {
-                    self.cat_downcast_if_needed(pat, cmt, variant_did)
-                },
-                _ => cmt
-            };
-
-            for fp in field_pats {
-                let field_ty = self.pat_ty_adjusted(&fp.node.pat)?; // see (*2)
-                let f_index = self.tcx.field_index(fp.node.id, self.tables);
-                let cmt_field = Rc::new(self.cat_field(pat, cmt.clone(), f_index,
-                                                       fp.node.ident, field_ty));
-                self.cat_pattern_(cmt_field, &fp.node.pat, op)?;
+
+            PatKind::Tuple(ref subpats, ddpos) => {
+                // (p1, ..., pN)
+                let expected_len = match self.pat_ty_unadjusted(&pat)?.sty {
+                    ty::Tuple(ref tys) => tys.len(),
+                    ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
+                };
+                for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
+                    let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
+                    let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
+                    let subcmt = Rc::new(
+                        self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
+                    self.cat_pattern_(subcmt, &subpat, op)?;
+                }
             }
-          }
-
-          PatKind::Binding(.., Some(ref subpat)) => {
-              self.cat_pattern_(cmt, &subpat, op)?;
-          }
-
-          PatKind::Tuple(ref subpats, ddpos) => {
-            // (p1, ..., pN)
-            let expected_len = match self.pat_ty_unadjusted(&pat)?.sty {
-                ty::Tuple(ref tys) => tys.len(),
-                ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
-            };
-            for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
-                let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
-                let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
-                let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
+
+                PatKind::Box(ref subpat) | PatKind::Ref(ref subpat, _) => {
+                // box p1, &p1, &mut p1.  we can ignore the mutability of
+                // PatKind::Ref since that information is already contained
+                // in the type.
+                let subcmt = Rc::new(self.cat_deref(pat, cmt, NoteNone)?);
                 self.cat_pattern_(subcmt, &subpat, op)?;
             }
-          }
-
-          PatKind::Box(ref subpat) | PatKind::Ref(ref subpat, _) => {
-            // box p1, &p1, &mut p1.  we can ignore the mutability of
-            // PatKind::Ref since that information is already contained
-            // in the type.
-            let subcmt = Rc::new(self.cat_deref(pat, cmt, NoteNone)?);
-            self.cat_pattern_(subcmt, &subpat, op)?;
-          }
-
-          PatKind::Slice(ref before, ref slice, ref after) => {
-            let element_ty = match cmt.ty.builtin_index() {
-                Some(ty) => ty,
-                None => {
-                    debug!("Explicit index of non-indexable type {:?}", cmt);
-                    return Err(());
+
+            PatKind::Slice(ref before, ref slice, ref after) => {
+                let element_ty = match cmt.ty.builtin_index() {
+                    Some(ty) => ty,
+                    None => {
+                        debug!("Explicit index of non-indexable type {:?}", cmt);
+                        return Err(());
+                    }
+                };
+                let context = InteriorOffsetKind::Pattern;
+                let elt_cmt = Rc::new(self.cat_index(pat, cmt, element_ty, context)?);
+                for before_pat in before {
+                    self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
+                }
+                if let Some(ref slice_pat) = *slice {
+                    self.cat_pattern_(elt_cmt.clone(), &slice_pat, op)?;
+                }
+                for after_pat in after {
+                    self.cat_pattern_(elt_cmt.clone(), &after_pat, op)?;
                 }
-            };
-            let context = InteriorOffsetKind::Pattern;
-            let elt_cmt = Rc::new(self.cat_index(pat, cmt, element_ty, context)?);
-            for before_pat in before {
-                self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
-            }
-            if let Some(ref slice_pat) = *slice {
-                self.cat_pattern_(elt_cmt.clone(), &slice_pat, op)?;
-            }
-            for after_pat in after {
-                self.cat_pattern_(elt_cmt.clone(), &after_pat, op)?;
             }
-          }
 
-          PatKind::Path(_) | PatKind::Binding(.., None) |
-          PatKind::Lit(..) | PatKind::Range(..) | PatKind::Wild => {
-            // always ok
-          }
+            PatKind::Path(_) | PatKind::Binding(.., None) |
+            PatKind::Lit(..) | PatKind::Range(..) | PatKind::Wild => {
+                // always ok
+            }
         }
 
         Ok(())
@@ -1489,59 +1480,59 @@ impl<'tcx> cmt_<'tcx> {
         }
     }
 
-    pub fn descriptive_string(&self, tcx: TyCtxt<'_, '_, '_>) -> String {
+    pub fn descriptive_string(&self, tcx: TyCtxt<'_, '_, '_>) -> Cow<'static, str> {
         match self.cat {
             Categorization::StaticItem => {
-                "static item".to_string()
+                "static item".into()
             }
             Categorization::Rvalue(..) => {
-                "non-place".to_string()
+                "non-place".into()
             }
             Categorization::Local(vid) => {
                 if tcx.hir.is_argument(vid) {
-                    "argument".to_string()
+                    "argument"
                 } else {
-                    "local variable".to_string()
-                }
+                    "local variable"
+                }.into()
             }
             Categorization::Deref(_, pk) => {
                 match self.upvar_cat() {
                     Some(&Categorization::Upvar(ref var)) => {
-                        var.to_string()
+                        var.to_string().into()
                     }
                     Some(_) => bug!(),
                     None => {
                         match pk {
                             Unique => {
-                                "`Box` content".to_string()
+                                "`Box` content"
                             }
                             UnsafePtr(..) => {
-                                "dereference of raw pointer".to_string()
+                                "dereference of raw pointer"
                             }
                             BorrowedPtr(..) => {
                                 match self.note {
-                                    NoteIndex => "indexed content".to_string(),
-                                    _ => "borrowed content".to_string(),
+                                    NoteIndex => "indexed content",
+                                    _ => "borrowed content"
                                 }
                             }
-                        }
+                        }.into()
                     }
                 }
             }
             Categorization::Interior(_, InteriorField(..)) => {
-                "field".to_string()
+                "field".into()
             }
             Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Index)) => {
-                "indexed content".to_string()
+                "indexed content".into()
             }
             Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Pattern)) => {
-                "pattern-bound indexed content".to_string()
+                "pattern-bound indexed content".into()
             }
             Categorization::Upvar(ref var) => {
-                var.to_string()
+                var.to_string().into()
             }
             Categorization::Downcast(ref cmt, _) => {
-                cmt.descriptive_string(tcx)
+                cmt.descriptive_string(tcx).into()
             }
         }
     }
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 9416d60c9d1..14293afc707 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -371,7 +371,9 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
                     return
                 }
 
-                for default_method in self.tcx.provided_trait_methods(trait_def_id) {
+                let provided_trait_methods = self.tcx.provided_trait_methods(trait_def_id);
+                self.worklist.reserve(provided_trait_methods.len());
+                for default_method in provided_trait_methods {
                     let node_id = self.tcx
                                       .hir
                                       .as_local_node_id(default_method.def_id)
@@ -394,7 +396,6 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
 #[derive(Clone)]
 pub struct ReachableSet(pub Lrc<NodeSet>);
 
-
 fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> ReachableSet {
     debug_assert!(crate_num == LOCAL_CRATE);
 
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 01b0d2c27a1..edb571da7db 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -459,13 +459,13 @@ impl<'tcx> ScopeTree {
         }
     }
 
-    pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(Scope, Scope) {
+    pub fn each_encl_scope<E>(&self, mut e: E) where E: FnMut(Scope, Scope) {
         for (&child, &parent) in &self.parent_map {
             e(child, parent.0)
         }
     }
 
-    pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&hir::ItemLocalId, Scope) {
+    pub fn each_var_scope<E>(&self, mut e: E) where E: FnMut(&hir::ItemLocalId, Scope) {
         for (child, &parent) in self.var_map.iter() {
             e(child, parent)
         }
@@ -515,10 +515,8 @@ impl<'tcx> ScopeTree {
 
     /// Returns the lifetime of the local variable `var_id`
     pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope {
-        match self.var_map.get(&var_id) {
-            Some(&r) => r,
-            None => { bug!("no enclosing scope for id {:?}", var_id); }
-        }
+        self.var_map.get(&var_id).cloned().unwrap_or_else(||
+            bug!("no enclosing scope for id {:?}", var_id))
     }
 
     pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> Option<Scope> {
@@ -559,8 +557,7 @@ impl<'tcx> ScopeTree {
         scope
     }
 
-    pub fn scopes_intersect(&self, scope1: Scope, scope2: Scope)
-                            -> bool {
+    pub fn scopes_intersect(&self, scope1: Scope, scope2: Scope) -> bool {
         self.is_subscope_of(scope1, scope2) ||
         self.is_subscope_of(scope2, scope1)
     }
@@ -584,14 +581,13 @@ impl<'tcx> ScopeTree {
             }
         }
 
-        debug!("is_subscope_of({:?}, {:?})=true",
-               subscope, superscope);
+        debug!("is_subscope_of({:?}, {:?})=true", subscope, superscope);
 
         return true;
     }
 
     /// Returns the id of the innermost containing body
-    pub fn containing_body(&self, mut scope: Scope)-> Option<hir::ItemLocalId> {
+    pub fn containing_body(&self, mut scope: Scope) -> Option<hir::ItemLocalId> {
         loop {
             if let ScopeData::CallSite = scope.data {
                 return Some(scope.item_local_id());
@@ -664,8 +660,8 @@ impl<'tcx> ScopeTree {
     /// Assuming that the provided region was defined within this `ScopeTree`,
     /// returns the outermost `Scope` that the region outlives.
     pub fn early_free_scope<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                       br: &ty::EarlyBoundRegion)
-                                       -> Scope {
+                                      br: &ty::EarlyBoundRegion)
+                                      -> Scope {
         let param_owner = tcx.parent_def_id(br.def_id).unwrap();
 
         let param_owner_id = tcx.hir.as_local_node_id(param_owner).unwrap();
@@ -828,10 +824,8 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
 fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &'tcx hir::Arm) {
     visitor.terminating_scopes.insert(arm.body.hir_id.local_id);
 
-    if let Some(ref g) = arm.guard {
-        match g {
-            hir::Guard::If(ref expr) => visitor.terminating_scopes.insert(expr.hir_id.local_id),
-        };
+    if let Some(hir::Guard::If(ref expr)) = arm.guard {
+        visitor.terminating_scopes.insert(expr.hir_id.local_id);
     }
 
     intravisit::walk_arm(visitor, arm);
@@ -890,11 +884,9 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
             // This ensures fixed size stacks.
 
             hir::ExprKind::Binary(
-                source_map::Spanned { node: hir::BinOpKind::And, .. },
-                _, ref r) |
+                source_map::Spanned { node: hir::BinOpKind::And, .. }, _, ref r) |
             hir::ExprKind::Binary(
-                source_map::Spanned { node: hir::BinOpKind::Or, .. },
-                _, ref r) => {
+                source_map::Spanned { node: hir::BinOpKind::Or, .. }, _, ref r) => {
                     // For shortcircuiting operators, mark the RHS as a terminating
                     // scope since it only executes conditionally.
                     terminating(r.hir_id.local_id);
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index c41c6f3cbe5..a10b387672a 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -25,6 +25,7 @@ use errors::DiagnosticBuilder;
 use rustc::lint;
 use rustc_data_structures::sync::Lrc;
 use session::Session;
+use std::borrow::Cow;
 use std::cell::Cell;
 use std::mem::replace;
 use syntax::ast;
@@ -360,17 +361,17 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         is_late_bound_map: |tcx, id| {
             let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
             tcx.resolve_lifetimes(LOCAL_CRATE)
-                .late_bound
-                .get(&id)
-                .cloned()
+               .late_bound
+               .get(&id)
+               .cloned()
         },
 
         object_lifetime_defaults_map: |tcx, id| {
             let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
             tcx.resolve_lifetimes(LOCAL_CRATE)
-                .object_lifetime_defaults
-                .get(&id)
-                .cloned()
+               .object_lifetime_defaults
+               .get(&id)
+               .cloned()
         },
 
         ..*providers
@@ -410,8 +411,8 @@ fn resolve_lifetimes<'tcx>(
     for (k, v) in named_region_map.object_lifetime_defaults {
         let hir_id = tcx.hir.node_to_hir_id(k);
         let map = rl.object_lifetime_defaults
-            .entry(hir_id.owner_local_def_id())
-            .or_default();
+                    .entry(hir_id.owner_local_def_id())
+                    .or_default();
         Lrc::get_mut(map)
             .unwrap()
             .insert(hir_id.local_id, Lrc::new(v));
@@ -676,7 +677,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                                         lifetime.span,
                                         E0657,
                                         "`impl Trait` can only capture lifetimes \
-                                        bound at the fn or impl level"
+                                         bound at the fn or impl level"
                                     );
                                     self.uninsert_lifetime_on_error(lifetime, def.unwrap());
                                 }
@@ -1250,24 +1251,24 @@ fn compute_object_lifetime_defaults(
                     let object_lifetime_default_reprs: String = result
                         .iter()
                         .map(|set| match *set {
-                            Set1::Empty => "BaseDefault".to_string(),
-                            Set1::One(Region::Static) => "'static".to_string(),
+                            Set1::Empty => "BaseDefault".into(),
+                            Set1::One(Region::Static) => "'static".into(),
                             Set1::One(Region::EarlyBound(mut i, _, _)) => {
                                 generics.params.iter().find_map(|param| match param.kind {
-                                        GenericParamKind::Lifetime { .. } => {
-                                            if i == 0 {
-                                                return Some(param.name.ident().to_string());
-                                            }
-                                            i -= 1;
-                                            None
+                                    GenericParamKind::Lifetime { .. } => {
+                                        if i == 0 {
+                                            return Some(param.name.ident().to_string().into());
                                         }
-                                        _ => None,
-                                    }).unwrap()
+                                        i -= 1;
+                                        None
+                                    }
+                                    _ => None,
+                                }).unwrap()
                             }
                             Set1::One(_) => bug!(),
-                            Set1::Many => "Ambiguous".to_string(),
+                            Set1::Many => "Ambiguous".into(),
                         })
-                        .collect::<Vec<String>>()
+                        .collect::<Vec<Cow<'static, str>>>()
                         .join(",");
                     tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
                 }
@@ -1420,16 +1421,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         def_ids.sort_by_key(|&def_id| self.tcx.def_path_hash(def_id));
 
         for def_id in def_ids {
-            debug!(
-                "check_uses_for_lifetimes_defined_by_scope: def_id = {:?}",
-                def_id,
-            );
+            debug!("check_uses_for_lifetimes_defined_by_scope: def_id = {:?}", def_id);
 
             let lifetimeuseset = self.lifetime_uses.remove(&def_id);
-            debug!(
-                "check_uses_for_lifetimes_defined_by_scope: lifetimeuseset = {:?}",
-                lifetimeuseset
-            );
+
+            debug!("check_uses_for_lifetimes_defined_by_scope: lifetimeuseset = {:?}",
+                   lifetimeuseset);
+
             match lifetimeuseset {
                 Some(LifetimeUseSet::One(lifetime)) => {
                     let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
@@ -1669,7 +1667,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                             "lifetimes used in `fn` or `Fn` syntax must be \
                              explicitly declared using `<...>` binders"
                         ).span_label(lifetime_ref.span, "in-band lifetime definition")
-                            .emit();
+                         .emit();
                     }
 
                     Region::Static
@@ -1689,7 +1687,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 "use of undeclared lifetime name `{}`",
                 lifetime_ref
             ).span_label(lifetime_ref.span, "undeclared lifetime")
-                .emit();
+             .emit();
         }
     }
 
@@ -1872,18 +1870,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 node: hir::TraitItemKind::Method(_, ref m),
                 ..
             }) => {
-                match self.tcx
+                if let hir::ItemKind::Trait(.., ref trait_items) = self.tcx
                     .hir
                     .expect_item(self.tcx.hir.get_parent(parent))
                     .node
                 {
-                    hir::ItemKind::Trait(.., ref trait_items) => {
-                        assoc_item_kind = trait_items
-                            .iter()
-                            .find(|ti| ti.id.node_id == parent)
-                            .map(|ti| ti.kind);
-                    }
-                    _ => {}
+                    assoc_item_kind = trait_items
+                        .iter()
+                        .find(|ti| ti.id.node_id == parent)
+                        .map(|ti| ti.kind);
                 }
                 match *m {
                     hir::TraitMethod::Required(_) => None,
@@ -1895,19 +1890,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 node: hir::ImplItemKind::Method(_, body),
                 ..
             }) => {
-                match self.tcx
+                if let hir::ItemKind::Impl(.., ref self_ty, ref impl_items) = self.tcx
                     .hir
                     .expect_item(self.tcx.hir.get_parent(parent))
                     .node
                 {
-                    hir::ItemKind::Impl(.., ref self_ty, ref impl_items) => {
-                        impl_self = Some(self_ty);
-                        assoc_item_kind = impl_items
-                            .iter()
-                            .find(|ii| ii.id.node_id == parent)
-                            .map(|ii| ii.kind);
-                    }
-                    _ => {}
+                    impl_self = Some(self_ty);
+                    assoc_item_kind = impl_items
+                        .iter()
+                        .find(|ii| ii.id.node_id == parent)
+                        .map(|ii| ii.kind);
                 }
                 Some(body)
             }
@@ -2255,9 +2247,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
 
                 Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return,
 
-                Scope::ObjectLifetimeDefault {
-                    lifetime: Some(l), ..
-                } => break l,
+                Scope::ObjectLifetimeDefault { lifetime: Some(l), .. } => break l,
             }
         };
         self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
@@ -2329,13 +2319,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                                     lifetime_i.name.ident(),
                                 ),
                             ).help(&format!(
-                                "you can use the `'static` lifetime directly, in place \
-                                    of `{}`",
+                                "you can use the `'static` lifetime directly, in place of `{}`",
                                 lifetime_i.name.ident(),
                             )).emit();
                         }
-                        hir::LifetimeName::Param(_)
-                        | hir::LifetimeName::Implicit => {
+                        hir::LifetimeName::Param(_) | hir::LifetimeName::Implicit => {
                             self.resolve_lifetime_ref(lt);
                         }
                     }
@@ -2492,8 +2480,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 /// Detects late-bound lifetimes and inserts them into
 /// `map.late_bound`.
 ///
@@ -2509,10 +2495,8 @@ fn insert_late_bound_lifetimes(
     decl: &hir::FnDecl,
     generics: &hir::Generics,
 ) {
-    debug!(
-        "insert_late_bound_lifetimes(decl={:?}, generics={:?})",
-        decl, generics
-    );
+    debug!("insert_late_bound_lifetimes(decl={:?}, generics={:?})",
+           decl, generics);
 
     let mut constrained_by_input = ConstrainedCollector {
         regions: FxHashSet(),
@@ -2526,10 +2510,8 @@ fn insert_late_bound_lifetimes(
     };
     intravisit::walk_fn_ret_ty(&mut appears_in_output, &decl.output);
 
-    debug!(
-        "insert_late_bound_lifetimes: constrained_by_input={:?}",
-        constrained_by_input.regions
-    );
+    debug!("insert_late_bound_lifetimes: constrained_by_input={:?}",
+           constrained_by_input.regions);
 
     // Walk the lifetimes that appear in where clauses.
     //
@@ -2541,15 +2523,12 @@ fn insert_late_bound_lifetimes(
     appears_in_where_clause.visit_generics(generics);
 
     for param in &generics.params {
-        match param.kind {
-            hir::GenericParamKind::Lifetime { .. } => {
-                if !param.bounds.is_empty() {
-                    // `'a: 'b` means both `'a` and `'b` are referenced
-                    appears_in_where_clause
-                        .regions.insert(hir::LifetimeName::Param(param.name.modern()));
-                }
+        if let hir::GenericParamKind::Lifetime { .. } = param.kind {
+            if !param.bounds.is_empty() {
+                // `'a: 'b` means both `'a` and `'b` are referenced
+                appears_in_where_clause
+                    .regions.insert(hir::LifetimeName::Param(param.name.modern()));
             }
-            hir::GenericParamKind::Type { .. } => {}
         }
     }
 
@@ -2661,10 +2640,10 @@ pub fn report_missing_lifetime_specifiers(
         if count > 1 { "s" } else { "" }
     );
 
-    let msg = if count > 1 {
-        format!("expected {} lifetime parameters", count)
+    let msg: Cow<'static, str> = if count > 1 {
+        format!("expected {} lifetime parameters", count).into()
     } else {
-        "expected lifetime parameter".to_string()
+        "expected lifetime parameter".into()
     };
 
     err.span_label(span, msg);
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index b7b149ea029..9dd13dd2272 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -164,8 +164,10 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
                 if let (&Some(attr::RustcDeprecation {since: dep_since, ..}),
                         &attr::Stable {since: stab_since}) = (&stab.rustc_depr, &stab.level) {
                     // Explicit version of iter::order::lt to handle parse errors properly
-                    for (dep_v, stab_v) in
-                            dep_since.as_str().split('.').zip(stab_since.as_str().split('.')) {
+                    for (dep_v, stab_v) in dep_since.as_str()
+                                                    .split('.')
+                                                    .zip(stab_since.as_str().split('.'))
+                    {
                         if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
                             match dep_v.cmp(&stab_v) {
                                 Ordering::Less => {
@@ -523,15 +525,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             Some(Def::Method(_)) |
             Some(Def::AssociatedTy(_)) |
             Some(Def::AssociatedConst(_)) => {
-                match self.associated_item(def_id).container {
-                    ty::TraitContainer(trait_def_id) => {
-                        // Trait methods do not declare visibility (even
-                        // for visibility info in cstore). Use containing
-                        // trait instead, so methods of pub traits are
-                        // themselves considered pub.
-                        def_id = trait_def_id;
-                    }
-                    _ => {}
+                if let ty::TraitContainer(trait_def_id) = self.associated_item(def_id).container {
+                    // Trait methods do not declare visibility (even
+                    // for visibility info in cstore). Use containing
+                    // trait instead, so methods of pub traits are
+                    // themselves considered pub.
+                    def_id = trait_def_id;
                 }
             }
             _ => {}
@@ -561,8 +560,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// `id`.
     pub fn eval_stability(self, def_id: DefId, id: Option<NodeId>, span: Span) -> EvalResult {
         if span.allows_unstable() {
-            debug!("stability: \
-                    skipping span={:?} since it is internal", span);
+            debug!("stability: skipping span={:?} since it is internal", span);
             return EvalResult::Allow;
         }
 
@@ -770,8 +768,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                     let param_env = self.tcx.param_env(def_id);
                     if !param_env.can_type_implement_copy(self.tcx, ty).is_ok() {
                         emit_feature_err(&self.tcx.sess.parse_sess,
-                                        "untagged_unions", item.span, GateIssue::Language,
-                                        "unions with non-`Copy` fields are unstable");
+                                         "untagged_unions", item.span, GateIssue::Language,
+                                         "unions with non-`Copy` fields are unstable");
                     }
                 }
             }
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 941bd4dda99..0d407765c9e 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -113,13 +113,13 @@ fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            items.$name().is_none() {
             if lang_items::$item == lang_items::PanicImplLangItem {
                 tcx.sess.err(&format!("`#[panic_handler]` function required, \
-                                        but not found"));
+                                       but not found"));
             } else if lang_items::$item == lang_items::OomLangItem {
                 tcx.sess.err(&format!("`#[alloc_error_handler]` function required, \
-                                        but not found"));
+                                       but not found"));
             } else {
                 tcx.sess.err(&format!("language item required, but not found: `{}`",
-                                        stringify!($name)));
+                                      stringify!($name)));
             }
         }
     )*
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 321257aefdb..0ef0d284770 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -38,6 +38,7 @@ use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
 use rustc_mir::util::suggest_ref_mut;
 use rustc::util::nodemap::FxHashSet;
 
+use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
 use std::fmt;
 use std::rc::Rc;
@@ -808,34 +809,34 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
 
         match err.code {
             err_mutbl => {
-                let descr = match err.cmt.note {
+                let descr: Cow<'static, str> = match err.cmt.note {
                     mc::NoteClosureEnv(_) | mc::NoteUpvarRef(_) => {
-                        self.cmt_to_string(&err.cmt)
+                        self.cmt_to_cow_str(&err.cmt)
                     }
                     _ => match opt_loan_path_is_field(&err.cmt) {
                         (None, true) => {
                             format!("{} of {} binding",
-                                    self.cmt_to_string(&err.cmt),
-                                    err.cmt.mutbl.to_user_str())
+                                    self.cmt_to_cow_str(&err.cmt),
+                                    err.cmt.mutbl.to_user_str()).into()
 
                         }
                         (None, false) => {
                             format!("{} {}",
                                     err.cmt.mutbl.to_user_str(),
-                                    self.cmt_to_string(&err.cmt))
+                                    self.cmt_to_cow_str(&err.cmt)).into()
 
                         }
                         (Some(lp), true) => {
                             format!("{} `{}` of {} binding",
-                                    self.cmt_to_string(&err.cmt),
+                                    self.cmt_to_cow_str(&err.cmt),
                                     self.loan_path_to_string(&lp),
-                                    err.cmt.mutbl.to_user_str())
+                                    err.cmt.mutbl.to_user_str()).into()
                         }
                         (Some(lp), false) => {
                             format!("{} {} `{}`",
                                     err.cmt.mutbl.to_user_str(),
-                                    self.cmt_to_string(&err.cmt),
-                                    self.loan_path_to_string(&lp))
+                                    self.cmt_to_cow_str(&err.cmt),
+                                    self.loan_path_to_string(&lp)).into()
                         }
                     }
                 };
@@ -1058,11 +1059,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
             err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
                 let descr = self.cmt_to_path_or_string(err.cmt);
                 let mut db = self.lifetime_too_short_for_reborrow(error_span, &descr, Origin::Ast);
-                let descr = match opt_loan_path(&err.cmt) {
+                let descr: Cow<'static, str> = match opt_loan_path(&err.cmt) {
                     Some(lp) => {
-                        format!("`{}`", self.loan_path_to_string(&lp))
+                        format!("`{}`", self.loan_path_to_string(&lp)).into()
                     }
-                    None => self.cmt_to_string(&err.cmt),
+                    None => self.cmt_to_cow_str(&err.cmt)
                 };
                 self.tcx.note_and_explain_region(
                     &self.region_scope_tree,
@@ -1477,14 +1478,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
         result
     }
 
-    pub fn cmt_to_string(&self, cmt: &mc::cmt_<'tcx>) -> String {
+    pub fn cmt_to_cow_str(&self, cmt: &mc::cmt_<'tcx>) -> Cow<'static, str> {
         cmt.descriptive_string(self.tcx)
     }
 
     pub fn cmt_to_path_or_string(&self, cmt: &mc::cmt_<'tcx>) -> String {
         match opt_loan_path(cmt) {
             Some(lp) => format!("`{}`", self.loan_path_to_string(&lp)),
-            None => self.cmt_to_string(cmt),
+            None => self.cmt_to_cow_str(cmt).into_owned(),
         }
     }
 }