about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-03-04 18:16:43 +0000
committerbors <bors@rust-lang.org>2018-03-04 18:16:43 +0000
commit259e4a67843d5fbe6761a5e442836d7109d72cbe (patch)
tree13689b1b24e4cd17b737a0892583e7888c915f7b /src
parent1e1bfc715f8dfe36a38d8fae36fcbe92e7463a3f (diff)
parent99c42dccfa7d00b6f488bcd61a5cf141d2112acf (diff)
downloadrust-259e4a67843d5fbe6761a5e442836d7109d72cbe.tar.gz
rust-259e4a67843d5fbe6761a5e442836d7109d72cbe.zip
Auto merge of #48592 - spastorino:borrowed_value_error, r=nikomatsakis
[NLL] Avoid borrowed value must be valid for lifetime '_#2r..." in errors

Closes #48428

- [x] If NLL is enabled, [do not invoke `note_and_explain_region`](https://github.com/rust-lang/rust/issues/48428#issuecomment-367691123)
- [x] Modify `-Zdump-nll-cause` to not print [the overwhelming debug output here](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/borrow_check/nll/region_infer/mod.rs#L1288-L1299). This way we should I believe at least get nice-ish output for [our original example](https://github.com/rust-lang/rust/issues/48428#issue-299364536).
- [x] Extend `explain_why_borrow_contains_point` to also work for "universal lifetimes" like the `'a` in [the example at the end of this comment](https://github.com/rust-lang/rust/issues/48428#issuecomment-367691123).
- [ ] Figure out how to enable causal information all the time (but that is https://github.com/rust-lang/rust/issues/46590).
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/error_reporting/mod.rs833
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs196
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs15
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/mod.rs127
-rw-r--r--src/test/ui/nll/borrowed-local-error.rs26
-rw-r--r--src/test/ui/nll/borrowed-local-error.stderr17
-rw-r--r--src/test/ui/nll/borrowed-temporary-error.rs26
-rw-r--r--src/test/ui/nll/borrowed-temporary-error.stderr14
-rw-r--r--src/test/ui/nll/borrowed-universal-error-2.rs22
-rw-r--r--src/test/ui/nll/borrowed-universal-error-2.stderr18
-rw-r--r--src/test/ui/nll/borrowed-universal-error.rs26
-rw-r--r--src/test/ui/nll/borrowed-universal-error.stderr18
-rw-r--r--src/test/ui/nll/capture-ref-in-struct.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr2
-rw-r--r--src/test/ui/nll/return-ref-mut-issue-46557.stderr2
18 files changed, 787 insertions, 563 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 700d06acf11..37a84361aea 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -56,7 +56,7 @@
 //! time of error detection.
 
 use infer;
-use super::{InferCtxt, TypeTrace, SubregionOrigin, RegionVariableOrigin, ValuePairs};
+use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
 use super::region_constraints::GenericKind;
 use super::lexical_region_resolve::RegionResolutionError;
 
@@ -81,54 +81,22 @@ mod need_type_info;
 pub mod nice_region_error;
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-    pub fn note_and_explain_region(self,
-                                   region_scope_tree: &region::ScopeTree,
-                                   err: &mut DiagnosticBuilder,
-                                   prefix: &str,
-                                   region: ty::Region<'tcx>,
-                                   suffix: &str) {
-        fn item_scope_tag(item: &hir::Item) -> &'static str {
-            match item.node {
-                hir::ItemImpl(..) => "impl",
-                hir::ItemStruct(..) => "struct",
-                hir::ItemUnion(..) => "union",
-                hir::ItemEnum(..) => "enum",
-                hir::ItemTrait(..) => "trait",
-                hir::ItemFn(..) => "function body",
-                _ => "item"
-            }
-        }
-
-        fn trait_item_scope_tag(item: &hir::TraitItem) -> &'static str {
-            match item.node {
-                hir::TraitItemKind::Method(..) => "method body",
-                hir::TraitItemKind::Const(..) |
-                hir::TraitItemKind::Type(..) => "associated item"
-            }
-        }
-
-        fn impl_item_scope_tag(item: &hir::ImplItem) -> &'static str {
-            match item.node {
-                hir::ImplItemKind::Method(..) => "method body",
-                hir::ImplItemKind::Const(..) |
-                hir::ImplItemKind::Type(_) => "associated item"
-            }
-        }
-
-        fn explain_span<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                        heading: &str, span: Span)
-                                        -> (String, Option<Span>) {
-            let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo());
-            (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1),
-             Some(span))
-        }
-
+    pub fn note_and_explain_region(
+        self,
+        region_scope_tree: &region::ScopeTree,
+        err: &mut DiagnosticBuilder,
+        prefix: &str,
+        region: ty::Region<'tcx>,
+        suffix: &str,
+    ) {
         let (description, span) = match *region {
             ty::ReScope(scope) => {
                 let new_string;
                 let unknown_scope = || {
-                    format!("{}unknown scope: {:?}{}.  Please report a bug.",
-                            prefix, scope, suffix)
+                    format!(
+                        "{}unknown scope: {:?}{}.  Please report a bug.",
+                        prefix, scope, suffix
+                    )
                 };
                 let span = scope.span(self, region_scope_tree);
                 let tag = match self.hir.find(scope.node_id(self, region_scope_tree)) {
@@ -137,15 +105,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                         hir::ExprCall(..) => "call",
                         hir::ExprMethodCall(..) => "method call",
                         hir::ExprMatch(.., hir::MatchSource::IfLetDesugar { .. }) => "if let",
-                        hir::ExprMatch(.., hir::MatchSource::WhileLetDesugar) =>  "while let",
-                        hir::ExprMatch(.., hir::MatchSource::ForLoopDesugar) =>  "for",
+                        hir::ExprMatch(.., hir::MatchSource::WhileLetDesugar) => "while let",
+                        hir::ExprMatch(.., hir::MatchSource::ForLoopDesugar) => "for",
                         hir::ExprMatch(..) => "match",
                         _ => "expression",
                     },
                     Some(hir_map::NodeStmt(_)) => "statement",
-                    Some(hir_map::NodeItem(it)) => item_scope_tag(&it),
-                    Some(hir_map::NodeTraitItem(it)) => trait_item_scope_tag(&it),
-                    Some(hir_map::NodeImplItem(it)) => impl_item_scope_tag(&it),
+                    Some(hir_map::NodeItem(it)) => Self::item_scope_tag(&it),
+                    Some(hir_map::NodeTraitItem(it)) => Self::trait_item_scope_tag(&it),
+                    Some(hir_map::NodeImplItem(it)) => Self::impl_item_scope_tag(&it),
                     Some(_) | None => {
                         err.span_note(span, &unknown_scope());
                         return;
@@ -153,74 +121,24 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 };
                 let scope_decorated_tag = match scope.data() {
                     region::ScopeData::Node(_) => tag,
-                    region::ScopeData::CallSite(_) => {
-                        "scope of call-site for function"
-                    }
-                    region::ScopeData::Arguments(_) => {
-                        "scope of function body"
-                    }
+                    region::ScopeData::CallSite(_) => "scope of call-site for function",
+                    region::ScopeData::Arguments(_) => "scope of function body",
                     region::ScopeData::Destruction(_) => {
                         new_string = format!("destruction scope surrounding {}", tag);
                         &new_string[..]
                     }
                     region::ScopeData::Remainder(r) => {
-                        new_string = format!("block suffix following statement {}",
-                                             r.first_statement_index.index());
+                        new_string = format!(
+                            "block suffix following statement {}",
+                            r.first_statement_index.index()
+                        );
                         &new_string[..]
                     }
                 };
-                explain_span(self, scope_decorated_tag, span)
+                self.explain_span(scope_decorated_tag, span)
             }
 
-            ty::ReEarlyBound(_) |
-            ty::ReFree(_) => {
-                let scope = region.free_region_binding_scope(self);
-                let node = self.hir.as_local_node_id(scope)
-                                   .unwrap_or(DUMMY_NODE_ID);
-                let unknown;
-                let tag = match self.hir.find(node) {
-                    Some(hir_map::NodeBlock(_)) |
-                    Some(hir_map::NodeExpr(_)) => "body",
-                    Some(hir_map::NodeItem(it)) => item_scope_tag(&it),
-                    Some(hir_map::NodeTraitItem(it)) => trait_item_scope_tag(&it),
-                    Some(hir_map::NodeImplItem(it)) => impl_item_scope_tag(&it),
-
-                    // this really should not happen, but it does:
-                    // FIXME(#27942)
-                    Some(_) => {
-                        unknown = format!("unexpected node ({}) for scope {:?}.  \
-                                           Please report a bug.",
-                                          self.hir.node_to_string(node), scope);
-                        &unknown
-                    }
-                    None => {
-                        unknown = format!("unknown node for scope {:?}.  \
-                                           Please report a bug.", scope);
-                        &unknown
-                    }
-                };
-                let (prefix, span) = match *region {
-                    ty::ReEarlyBound(ref br) => {
-                        (format!("the lifetime {} as defined on", br.name),
-                         self.sess.codemap().def_span(self.hir.span(node)))
-                    }
-                    ty::ReFree(ref fr) => {
-                        match fr.bound_region {
-                            ty::BrAnon(idx) => {
-                                (format!("the anonymous lifetime #{} defined on", idx + 1),
-                                 self.hir.span(node))
-                            }
-                            ty::BrFresh(_) => ("an anonymous lifetime defined on".to_owned(),
-                                               self.hir.span(node)),
-                            _ => (format!("the lifetime {} as defined on", fr.bound_region),
-                                  self.sess.codemap().def_span(self.hir.span(node))),
-                        }
-                    }
-                    _ => bug!()
-                };
-                let (msg, opt_span) = explain_span(self, tag, span);
-                (format!("{} {}", prefix, msg), opt_span)
-            }
+            ty::ReEarlyBound(_) | ty::ReFree(_) => self.msg_span_from_free_region(region),
 
             ty::ReStatic => ("the static lifetime".to_owned(), None),
 
@@ -231,35 +149,144 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             //
             // We shouldn't really be having unification failures with ReVar
             // and ReLateBound though.
-            ty::ReSkolemized(..) |
-            ty::ReVar(_) |
-            ty::ReLateBound(..) |
-            ty::ReErased => {
+            ty::ReSkolemized(..) | ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
                 (format!("lifetime {:?}", region), None)
             }
 
             // We shouldn't encounter an error message with ReClosureBound.
             ty::ReClosureBound(..) => {
-                bug!(
-                    "encountered unexpected ReClosureBound: {:?}",
-                    region,
+                bug!("encountered unexpected ReClosureBound: {:?}", region,);
+            }
+        };
+
+        TyCtxt::emit_msg_span(err, prefix, description, span, suffix);
+    }
+
+    pub fn note_and_explain_free_region(
+        self,
+        err: &mut DiagnosticBuilder,
+        prefix: &str,
+        region: ty::Region<'tcx>,
+        suffix: &str,
+    ) {
+        let (description, span) = self.msg_span_from_free_region(region);
+
+        TyCtxt::emit_msg_span(err, prefix, description, span, suffix);
+    }
+
+    fn msg_span_from_free_region(self, region: ty::Region<'tcx>) -> (String, Option<Span>) {
+        let scope = region.free_region_binding_scope(self);
+        let node = self.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID);
+        let unknown;
+        let tag = match self.hir.find(node) {
+            Some(hir_map::NodeBlock(_)) | Some(hir_map::NodeExpr(_)) => "body",
+            Some(hir_map::NodeItem(it)) => Self::item_scope_tag(&it),
+            Some(hir_map::NodeTraitItem(it)) => Self::trait_item_scope_tag(&it),
+            Some(hir_map::NodeImplItem(it)) => Self::impl_item_scope_tag(&it),
+
+            // this really should not happen, but it does:
+            // FIXME(#27942)
+            Some(_) => {
+                unknown = format!(
+                    "unexpected node ({}) for scope {:?}.  \
+                     Please report a bug.",
+                    self.hir.node_to_string(node),
+                    scope
+                );
+                &unknown
+            }
+            None => {
+                unknown = format!(
+                    "unknown node for scope {:?}.  \
+                     Please report a bug.",
+                    scope
                 );
+                &unknown
             }
         };
+        let (prefix, span) = match *region {
+            ty::ReEarlyBound(ref br) => (
+                format!("the lifetime {} as defined on", br.name),
+                self.sess.codemap().def_span(self.hir.span(node)),
+            ),
+            ty::ReFree(ref fr) => match fr.bound_region {
+                ty::BrAnon(idx) => (
+                    format!("the anonymous lifetime #{} defined on", idx + 1),
+                    self.hir.span(node),
+                ),
+                ty::BrFresh(_) => (
+                    "an anonymous lifetime defined on".to_owned(),
+                    self.hir.span(node),
+                ),
+                _ => (
+                    format!("the lifetime {} as defined on", fr.bound_region),
+                    self.sess.codemap().def_span(self.hir.span(node)),
+                ),
+            },
+            _ => bug!(),
+        };
+        let (msg, opt_span) = self.explain_span(tag, span);
+        (format!("{} {}", prefix, msg), opt_span)
+    }
+
+    fn emit_msg_span(
+        err: &mut DiagnosticBuilder,
+        prefix: &str,
+        description: String,
+        span: Option<Span>,
+        suffix: &str,
+    ) {
         let message = format!("{}{}{}", prefix, description, suffix);
+
         if let Some(span) = span {
             err.span_note(span, &message);
         } else {
             err.note(&message);
         }
     }
+
+    fn item_scope_tag(item: &hir::Item) -> &'static str {
+        match item.node {
+            hir::ItemImpl(..) => "impl",
+            hir::ItemStruct(..) => "struct",
+            hir::ItemUnion(..) => "union",
+            hir::ItemEnum(..) => "enum",
+            hir::ItemTrait(..) => "trait",
+            hir::ItemFn(..) => "function body",
+            _ => "item",
+        }
+    }
+
+    fn trait_item_scope_tag(item: &hir::TraitItem) -> &'static str {
+        match item.node {
+            hir::TraitItemKind::Method(..) => "method body",
+            hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => "associated item",
+        }
+    }
+
+    fn impl_item_scope_tag(item: &hir::ImplItem) -> &'static str {
+        match item.node {
+            hir::ImplItemKind::Method(..) => "method body",
+            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) => "associated item",
+        }
+    }
+
+    fn explain_span(self, heading: &str, span: Span) -> (String, Option<Span>) {
+        let lo = self.sess.codemap().lookup_char_pos_adj(span.lo());
+        (
+            format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1),
+            Some(span),
+        )
+    }
 }
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    pub fn report_region_errors(&self,
-                                region_scope_tree: &region::ScopeTree,
-                                errors: &Vec<RegionResolutionError<'tcx>>,
-                                will_later_be_reported_by_nll: bool) {
+    pub fn report_region_errors(
+        &self,
+        region_scope_tree: &region::ScopeTree,
+        errors: &Vec<RegionResolutionError<'tcx>>,
+        will_later_be_reported_by_nll: bool,
+    ) {
         debug!("report_region_errors(): {} errors to start", errors.len());
 
         if will_later_be_reported_by_nll && self.tcx.sess.nll() {
@@ -273,17 +300,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             // But with -Znll, it's nice to have some note for later.
             for error in errors {
                 match *error {
-                    RegionResolutionError::ConcreteFailure(ref origin, ..) |
-                    RegionResolutionError::GenericBoundFailure(ref origin, ..) => {
-                        self.tcx.sess.span_warn(
-                            origin.span(),
-                            "not reporting region error due to -Znll");
+                    RegionResolutionError::ConcreteFailure(ref origin, ..)
+                    | RegionResolutionError::GenericBoundFailure(ref origin, ..) => {
+                        self.tcx
+                            .sess
+                            .span_warn(origin.span(), "not reporting region error due to -Znll");
                     }
 
                     RegionResolutionError::SubSupConflict(ref rvo, ..) => {
-                        self.tcx.sess.span_warn(
-                            rvo.span(),
-                            "not reporting region error due to -Znll");
+                        self.tcx
+                            .sess
+                            .span_warn(rvo.span(), "not reporting region error due to -Znll");
                     }
                 }
             }
@@ -295,7 +322,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         // together into a `ProcessedErrors` group:
         let errors = self.process_errors(errors);
 
-        debug!("report_region_errors: {} errors after preprocessing", errors.len());
+        debug!(
+            "report_region_errors: {} errors after preprocessing",
+            errors.len()
+        );
 
         for error in errors {
             debug!("report_region_errors: error = {:?}", error);
@@ -310,7 +340,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     // the error. If all of these fails, we fall back to a rather
                     // general bit of code that displays the error information
                     RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
-                        self.report_concrete_failure(region_scope_tree, origin, sub, sup).emit();
+                        self.report_concrete_failure(region_scope_tree, origin, sub, sup)
+                            .emit();
                     }
 
                     RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => {
@@ -323,17 +354,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                         );
                     }
 
-                    RegionResolutionError::SubSupConflict(var_origin,
-                                                          sub_origin,
-                                                          sub_r,
-                                                          sup_origin,
-                                                          sup_r) => {
-                        self.report_sub_sup_conflict(region_scope_tree,
-                                                     var_origin,
-                                                     sub_origin,
-                                                     sub_r,
-                                                     sup_origin,
-                                                     sup_r);
+                    RegionResolutionError::SubSupConflict(
+                        var_origin,
+                        sub_origin,
+                        sub_r,
+                        sup_origin,
+                        sup_r,
+                    ) => {
+                        self.report_sub_sup_conflict(
+                            region_scope_tree,
+                            var_origin,
+                            sub_origin,
+                            sub_r,
+                            sup_origin,
+                            sup_r,
+                        );
                     }
                 }
             }
@@ -350,8 +385,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     // The method also attempts to weed out messages that seem like
     // duplicates that will be unhelpful to the end-user. But
     // obviously it never weeds out ALL errors.
-    fn process_errors(&self, errors: &Vec<RegionResolutionError<'tcx>>)
-                      -> Vec<RegionResolutionError<'tcx>> {
+    fn process_errors(
+        &self,
+        errors: &Vec<RegionResolutionError<'tcx>>,
+    ) -> Vec<RegionResolutionError<'tcx>> {
         debug!("process_errors()");
 
         // We want to avoid reporting generic-bound failures if we can
@@ -368,15 +405,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 
         let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e {
             RegionResolutionError::GenericBoundFailure(..) => true,
-            RegionResolutionError::ConcreteFailure(..) |
-            RegionResolutionError::SubSupConflict(..) => false,
+            RegionResolutionError::ConcreteFailure(..)
+            | RegionResolutionError::SubSupConflict(..) => false,
         };
 
-
         let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
             errors.clone()
         } else {
-            errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
+            errors
+                .iter()
+                .filter(|&e| !is_bound_failure(e))
+                .cloned()
+                .collect()
         };
 
         // sort the errors by span, for better error message stability.
@@ -389,10 +429,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 
     /// Adds a note if the types come from similarly named crates
-    fn check_and_note_conflicting_crates(&self,
-                                         err: &mut DiagnosticBuilder,
-                                         terr: &TypeError<'tcx>,
-                                         sp: Span) {
+    fn check_and_note_conflicting_crates(
+        &self,
+        err: &mut DiagnosticBuilder,
+        terr: &TypeError<'tcx>,
+        sp: Span,
+    ) {
         let report_path_match = |err: &mut DiagnosticBuilder, did1: DefId, did2: DefId| {
             // Only external crates, if either is from a local
             // module we could have false positives
@@ -403,12 +445,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 let found_abs_path = self.tcx.absolute_item_path_str(did2);
                 // We compare strings because DefPath can be different
                 // for imported and non-imported crates
-                if exp_path == found_path
-                || exp_abs_path == found_abs_path {
+                if exp_path == found_path || exp_abs_path == found_abs_path {
                     let crate_name = self.tcx.crate_name(did1.krate);
-                    err.span_note(sp, &format!("Perhaps two different versions \
-                                                of crate `{}` are being used?",
-                                               crate_name));
+                    err.span_note(
+                        sp,
+                        &format!(
+                            "Perhaps two different versions \
+                             of crate `{}` are being used?",
+                            crate_name
+                        ),
+                    );
                 }
             }
         };
@@ -419,24 +465,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 match (&exp_found.expected.sty, &exp_found.found.sty) {
                     (&ty::TyAdt(exp_adt, _), &ty::TyAdt(found_adt, _)) => {
                         report_path_match(err, exp_adt.did, found_adt.did);
-                    },
-                    _ => ()
+                    }
+                    _ => (),
                 }
-            },
+            }
             TypeError::Traits(ref exp_found) => {
                 report_path_match(err, exp_found.expected, exp_found.found);
-            },
-            _ => () // FIXME(#22750) handle traits and stuff
+            }
+            _ => (), // FIXME(#22750) handle traits and stuff
         }
     }
 
-    fn note_error_origin(&self,
-                         err: &mut DiagnosticBuilder<'tcx>,
-                         cause: &ObligationCause<'tcx>)
-    {
+    fn note_error_origin(&self, err: &mut DiagnosticBuilder<'tcx>, cause: &ObligationCause<'tcx>) {
         match cause.code {
             ObligationCauseCode::MatchExpressionArm { arm_span, source } => match source {
-                hir::MatchSource::IfLetDesugar {..} => {
+                hir::MatchSource::IfLetDesugar { .. } => {
                     let msg = "`if let` arm with an incompatible type";
                     if self.tcx.sess.codemap().is_multiline(arm_span) {
                         err.span_note(arm_span, msg);
@@ -453,7 +496,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     }
                 }
             },
-            _ => ()
+            _ => (),
         }
     }
 
@@ -470,13 +513,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     /// Bar<Qux>
     /// -------- this type is the same as a type argument in the other type, not highlighted
     /// ```
-    fn highlight_outer(&self,
-                       value: &mut DiagnosticStyledString,
-                       other_value: &mut DiagnosticStyledString,
-                       name: String,
-                       sub: &ty::subst::Substs<'tcx>,
-                       pos: usize,
-                       other_ty: &Ty<'tcx>) {
+    fn highlight_outer(
+        &self,
+        value: &mut DiagnosticStyledString,
+        other_value: &mut DiagnosticStyledString,
+        name: String,
+        sub: &ty::subst::Substs<'tcx>,
+        pos: usize,
+        other_ty: &Ty<'tcx>,
+    ) {
         // `value` and `other_value` hold two incomplete type representation for display.
         // `name` is the path of both types being compared. `sub`
         value.push_highlighted(name);
@@ -486,14 +531,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         }
 
         // Output the lifetimes fot the first type
-        let lifetimes = sub.regions().map(|lifetime| {
-            let s = format!("{}", lifetime);
-            if s.is_empty() {
-                "'_".to_string()
-            } else {
-                s
-            }
-        }).collect::<Vec<_>>().join(", ");
+        let lifetimes = sub.regions()
+            .map(|lifetime| {
+                let s = format!("{}", lifetime);
+                if s.is_empty() {
+                    "'_".to_string()
+                } else {
+                    s
+                }
+            })
+            .collect::<Vec<_>>()
+            .join(", ");
         if !lifetimes.is_empty() {
             if sub.regions().count() < len {
                 value.push_normal(lifetimes + &", ");
@@ -543,13 +591,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     /// Bar<Qux>
     /// -------- this type is the same as a type argument in the other type, not highlighted
     /// ```
-    fn cmp_type_arg(&self,
-                    mut t1_out: &mut DiagnosticStyledString,
-                    mut t2_out: &mut DiagnosticStyledString,
-                    path: String,
-                    sub: &ty::subst::Substs<'tcx>,
-                    other_path: String,
-                    other_ty: &Ty<'tcx>) -> Option<()> {
+    fn cmp_type_arg(
+        &self,
+        mut t1_out: &mut DiagnosticStyledString,
+        mut t2_out: &mut DiagnosticStyledString,
+        path: String,
+        sub: &ty::subst::Substs<'tcx>,
+        other_path: String,
+        other_ty: &Ty<'tcx>,
+    ) -> Option<()> {
         for (i, ta) in sub.types().enumerate() {
             if &ta == other_ty {
                 self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty);
@@ -567,11 +617,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 
     /// Add a `,` to the type representation only if it is appropriate.
-    fn push_comma(&self,
-                  value: &mut DiagnosticStyledString,
-                  other_value: &mut DiagnosticStyledString,
-                  len: usize,
-                  pos: usize) {
+    fn push_comma(
+        &self,
+        value: &mut DiagnosticStyledString,
+        other_value: &mut DiagnosticStyledString,
+        len: usize,
+        pos: usize,
+    ) {
         if len > 0 && pos != len - 1 {
             value.push_normal(", ");
             other_value.push_normal(", ");
@@ -580,39 +632,39 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 
     /// Compare two given types, eliding parts that are the same between them and highlighting
     /// relevant differences, and return two representation of those types for highlighted printing.
-    fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>)
-        -> (DiagnosticStyledString, DiagnosticStyledString)
-    {
+    fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagnosticStyledString, DiagnosticStyledString) {
         fn equals<'tcx>(a: &Ty<'tcx>, b: &Ty<'tcx>) -> bool {
             match (&a.sty, &b.sty) {
                 (a, b) if *a == *b => true,
-                (&ty::TyInt(_), &ty::TyInfer(ty::InferTy::IntVar(_))) |
-                (&ty::TyInfer(ty::InferTy::IntVar(_)), &ty::TyInt(_)) |
-                (&ty::TyInfer(ty::InferTy::IntVar(_)), &ty::TyInfer(ty::InferTy::IntVar(_))) |
-                (&ty::TyFloat(_), &ty::TyInfer(ty::InferTy::FloatVar(_))) |
-                (&ty::TyInfer(ty::InferTy::FloatVar(_)), &ty::TyFloat(_)) |
-                (&ty::TyInfer(ty::InferTy::FloatVar(_)),
-                 &ty::TyInfer(ty::InferTy::FloatVar(_))) => true,
+                (&ty::TyInt(_), &ty::TyInfer(ty::InferTy::IntVar(_)))
+                | (&ty::TyInfer(ty::InferTy::IntVar(_)), &ty::TyInt(_))
+                | (&ty::TyInfer(ty::InferTy::IntVar(_)), &ty::TyInfer(ty::InferTy::IntVar(_)))
+                | (&ty::TyFloat(_), &ty::TyInfer(ty::InferTy::FloatVar(_)))
+                | (&ty::TyInfer(ty::InferTy::FloatVar(_)), &ty::TyFloat(_))
+                | (
+                    &ty::TyInfer(ty::InferTy::FloatVar(_)),
+                    &ty::TyInfer(ty::InferTy::FloatVar(_)),
+                ) => true,
                 _ => false,
             }
         }
 
-        fn push_ty_ref<'tcx>(r: &ty::Region<'tcx>,
-                             tnm: &ty::TypeAndMut<'tcx>,
-                             s: &mut DiagnosticStyledString) {
+        fn push_ty_ref<'tcx>(
+            r: &ty::Region<'tcx>,
+            tnm: &ty::TypeAndMut<'tcx>,
+            s: &mut DiagnosticStyledString,
+        ) {
             let r = &format!("{}", r);
-            s.push_highlighted(format!("&{}{}{}",
-                                       r,
-                                       if r == "" {
-                                           ""
-                                       } else {
-                                           " "
-                                       },
-                                       if tnm.mutbl == hir::MutMutable {
-                                          "mut "
-                                       } else {
-                                           ""
-                                       }));
+            s.push_highlighted(format!(
+                "&{}{}{}",
+                r,
+                if r == "" { "" } else { " " },
+                if tnm.mutbl == hir::MutMutable {
+                    "mut "
+                } else {
+                    ""
+                }
+            ));
             s.push_normal(format!("{}", tnm.ty));
         }
 
@@ -705,12 +757,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     //     Foo<Bar<Qux>
                     //         ------- this type argument is exactly the same as the other type
                     //     Bar<Qux>
-                    if self.cmp_type_arg(&mut values.0,
-                                         &mut values.1,
-                                         path1.clone(),
-                                         sub1,
-                                         path2.clone(),
-                                         &t2).is_some() {
+                    if self.cmp_type_arg(
+                        &mut values.0,
+                        &mut values.1,
+                        path1.clone(),
+                        sub1,
+                        path2.clone(),
+                        &t2,
+                    ).is_some()
+                    {
                         return values;
                     }
                     // Check for case:
@@ -718,19 +773,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     //     Bar<Qux>
                     //     Foo<Bar<Qux>>
                     //         ------- this type argument is exactly the same as the other type
-                    if self.cmp_type_arg(&mut values.1,
-                                         &mut values.0,
-                                         path2,
-                                         sub2,
-                                         path1,
-                                         &t1).is_some() {
+                    if self.cmp_type_arg(&mut values.1, &mut values.0, path2, sub2, path1, &t1)
+                        .is_some()
+                    {
                         return values;
                     }
 
                     // We couldn't find anything in common, highlight everything.
                     //     let x: Bar<Qux> = y::<Foo<Zar>>();
-                    (DiagnosticStyledString::highlighted(format!("{}", t1)),
-                     DiagnosticStyledString::highlighted(format!("{}", t2)))
+                    (
+                        DiagnosticStyledString::highlighted(format!("{}", t1)),
+                        DiagnosticStyledString::highlighted(format!("{}", t2)),
+                    )
                 }
             }
 
@@ -759,28 +813,36 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             _ => {
                 if t1 == t2 {
                     // The two types are the same, elide and don't highlight.
-                    (DiagnosticStyledString::normal("_"), DiagnosticStyledString::normal("_"))
+                    (
+                        DiagnosticStyledString::normal("_"),
+                        DiagnosticStyledString::normal("_"),
+                    )
                 } else {
                     // We couldn't find anything in common, highlight everything.
-                    (DiagnosticStyledString::highlighted(format!("{}", t1)),
-                     DiagnosticStyledString::highlighted(format!("{}", t2)))
+                    (
+                        DiagnosticStyledString::highlighted(format!("{}", t1)),
+                        DiagnosticStyledString::highlighted(format!("{}", t2)),
+                    )
                 }
             }
         }
     }
 
-    pub fn note_type_err(&self,
-                         diag: &mut DiagnosticBuilder<'tcx>,
-                         cause: &ObligationCause<'tcx>,
-                         secondary_span: Option<(Span, String)>,
-                         mut values: Option<ValuePairs<'tcx>>,
-                         terr: &TypeError<'tcx>)
-    {
+    pub fn note_type_err(
+        &self,
+        diag: &mut DiagnosticBuilder<'tcx>,
+        cause: &ObligationCause<'tcx>,
+        secondary_span: Option<(Span, String)>,
+        mut values: Option<ValuePairs<'tcx>>,
+        terr: &TypeError<'tcx>,
+    ) {
         // For some types of errors, expected-found does not make
         // sense, so just ignore the values we were given.
         match terr {
-            TypeError::CyclicTy(_) => { values = None; }
-            _ => { }
+            TypeError::CyclicTy(_) => {
+                values = None;
+            }
+            _ => {}
         }
 
         let (expected_found, exp_found, is_simple_error) = match values {
@@ -788,8 +850,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             Some(values) => {
                 let (is_simple_error, exp_found) = match values {
                     ValuePairs::Types(exp_found) => {
-                        let is_simple_err = exp_found.expected.is_primitive()
-                            && exp_found.found.is_primitive();
+                        let is_simple_err =
+                            exp_found.expected.is_primitive() && exp_found.found.is_primitive();
 
                         (is_simple_err, Some(exp_found))
                     }
@@ -800,7 +862,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     None => {
                         // Derived error. Cancel the emitter.
                         self.tcx.sess.diagnostic().cancel(diag);
-                        return
+                        return;
                     }
                 };
                 (vals, exp_found, is_simple_error)
@@ -818,9 +880,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             match (terr, is_simple_error, expected == found) {
                 (&TypeError::Sorts(ref values), false, true) => {
                     diag.note_expected_found_extra(
-                        &"type", expected, found,
+                        &"type",
+                        expected,
+                        found,
                         &format!(" ({})", values.expected.sort_string(self.tcx)),
-                        &format!(" ({})", values.found.sort_string(self.tcx)));
+                        &format!(" ({})", values.found.sort_string(self.tcx)),
+                    );
                 }
                 (_, false, _) => {
                     if let Some(exp_found) = exp_found {
@@ -828,12 +893,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             TypeVariants::TyFnDef(def, _) => {
                                 (Some(def), Some(self.tcx.fn_sig(def).output()))
                             }
-                            _ => (None, None)
+                            _ => (None, None),
                         };
 
                         let exp_is_struct = match exp_found.expected.sty {
                             TypeVariants::TyAdt(def, _) => def.is_struct(),
-                            _ => false
+                            _ => false,
                         };
 
                         if let (Some(def_id), Some(ret_ty)) = (def_id, ret_ty) {
@@ -861,14 +926,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         self.note_error_origin(diag, &cause);
     }
 
-    pub fn report_and_explain_type_error(&self,
-                                         trace: TypeTrace<'tcx>,
-                                         terr: &TypeError<'tcx>)
-                                         -> DiagnosticBuilder<'tcx>
-    {
-        debug!("report_and_explain_type_error(trace={:?}, terr={:?})",
-               trace,
-               terr);
+    pub fn report_and_explain_type_error(
+        &self,
+        trace: TypeTrace<'tcx>,
+        terr: &TypeError<'tcx>,
+    ) -> DiagnosticBuilder<'tcx> {
+        debug!(
+            "report_and_explain_type_error(trace={:?}, terr={:?})",
+            trace, terr
+        );
 
         let span = trace.cause.span(&self.tcx);
         let failure_code = trace.cause.as_failure_code(terr);
@@ -890,9 +956,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         diag
     }
 
-    fn values_str(&self, values: &ValuePairs<'tcx>)
-        -> Option<(DiagnosticStyledString, DiagnosticStyledString)>
-    {
+    fn values_str(
+        &self,
+        values: &ValuePairs<'tcx>,
+    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> {
         match *values {
             infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found),
             infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found),
@@ -900,9 +967,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    fn expected_found_str_ty(&self,
-                             exp_found: &ty::error::ExpectedFound<Ty<'tcx>>)
-                             -> Option<(DiagnosticStyledString, DiagnosticStyledString)> {
+    fn expected_found_str_ty(
+        &self,
+        exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
+    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> {
         let exp_found = self.resolve_type_vars_if_possible(exp_found);
         if exp_found.references_error() {
             return None;
@@ -914,25 +982,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     /// Returns a string of the form "expected `{}`, found `{}`".
     fn expected_found_str<T: fmt::Display + TypeFoldable<'tcx>>(
         &self,
-        exp_found: &ty::error::ExpectedFound<T>)
-        -> Option<(DiagnosticStyledString, DiagnosticStyledString)>
-    {
+        exp_found: &ty::error::ExpectedFound<T>,
+    ) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> {
         let exp_found = self.resolve_type_vars_if_possible(exp_found);
         if exp_found.references_error() {
             return None;
         }
 
-        Some((DiagnosticStyledString::highlighted(format!("{}", exp_found.expected)),
-              DiagnosticStyledString::highlighted(format!("{}", exp_found.found))))
+        Some((
+            DiagnosticStyledString::highlighted(format!("{}", exp_found.expected)),
+            DiagnosticStyledString::highlighted(format!("{}", exp_found.found)),
+        ))
     }
 
-    pub fn report_generic_bound_failure(&self,
-                                        region_scope_tree: &region::ScopeTree,
-                                        span: Span,
-                                        origin: Option<SubregionOrigin<'tcx>>,
-                                        bound_kind: GenericKind<'tcx>,
-                                        sub: Region<'tcx>)
-    {
+    pub fn report_generic_bound_failure(
+        &self,
+        region_scope_tree: &region::ScopeTree,
+        span: Span,
+        origin: Option<SubregionOrigin<'tcx>>,
+        bound_kind: GenericKind<'tcx>,
+        sub: Region<'tcx>,
+    ) {
         // Attempt to obtain the span of the parameter so we can
         // suggest adding an explicit lifetime bound to it.
         let type_param_span = match (self.in_progress_tables, bound_kind) {
@@ -958,8 +1028,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             // `sp` only covers `T`, change it so that it covers
                             // `T:` when appropriate
                             let sp = if has_lifetimes {
-                                sp.to(self.tcx.sess.codemap().next_point(
-                                        self.tcx.sess.codemap().next_point(sp)))
+                                sp.to(self.tcx
+                                    .sess
+                                    .codemap()
+                                    .next_point(self.tcx.sess.codemap().next_point(sp)))
                             } else {
                                 sp
                             };
@@ -974,37 +1046,39 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         };
 
         let labeled_user_string = match bound_kind {
-            GenericKind::Param(ref p) =>
-                format!("the parameter type `{}`", p),
-            GenericKind::Projection(ref p) =>
-                format!("the associated type `{}`", p),
+            GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
+            GenericKind::Projection(ref p) => format!("the associated type `{}`", p),
         };
 
         if let Some(SubregionOrigin::CompareImplMethodObligation {
-            span, item_name, impl_item_def_id, trait_item_def_id,
-        }) = origin {
-            self.report_extra_impl_obligation(span,
-                                              item_name,
-                                              impl_item_def_id,
-                                              trait_item_def_id,
-                                              &format!("`{}: {}`", bound_kind, sub))
-                .emit();
+            span,
+            item_name,
+            impl_item_def_id,
+            trait_item_def_id,
+        }) = origin
+        {
+            self.report_extra_impl_obligation(
+                span,
+                item_name,
+                impl_item_def_id,
+                trait_item_def_id,
+                &format!("`{}: {}`", bound_kind, sub),
+            ).emit();
             return;
         }
 
-        fn binding_suggestion<'tcx, S: fmt::Display>(err: &mut DiagnosticBuilder<'tcx>,
-                                                     type_param_span: Option<(Span, bool)>,
-                                                     bound_kind: GenericKind<'tcx>,
-                                                     sub: S) {
-            let consider = &format!("consider adding an explicit lifetime bound `{}: {}`...",
-                                    bound_kind,
-                                    sub);
+        fn binding_suggestion<'tcx, S: fmt::Display>(
+            err: &mut DiagnosticBuilder<'tcx>,
+            type_param_span: Option<(Span, bool)>,
+            bound_kind: GenericKind<'tcx>,
+            sub: S,
+        ) {
+            let consider = &format!(
+                "consider adding an explicit lifetime bound `{}: {}`...",
+                bound_kind, sub
+            );
             if let Some((sp, has_lifetimes)) = type_param_span {
-                let tail = if has_lifetimes {
-                    " + "
-                } else {
-                    ""
-                };
+                let tail = if has_lifetimes { " + " } else { "" };
                 let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
                 err.span_suggestion_short(sp, consider, suggestion);
             } else {
@@ -1013,44 +1087,56 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         }
 
         let mut err = match *sub {
-            ty::ReEarlyBound(_) |
-            ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => {
+            ty::ReEarlyBound(_)
+            | ty::ReFree(ty::FreeRegion {
+                bound_region: ty::BrNamed(..),
+                ..
+            }) => {
                 // Does the required lifetime have a nice name we can print?
-                let mut err = struct_span_err!(self.tcx.sess,
-                                               span,
-                                               E0309,
-                                               "{} may not live long enough",
-                                               labeled_user_string);
+                let mut err = struct_span_err!(
+                    self.tcx.sess,
+                    span,
+                    E0309,
+                    "{} may not live long enough",
+                    labeled_user_string
+                );
                 binding_suggestion(&mut err, type_param_span, bound_kind, sub);
                 err
             }
 
             ty::ReStatic => {
                 // Does the required lifetime have a nice name we can print?
-                let mut err = struct_span_err!(self.tcx.sess,
-                                               span,
-                                               E0310,
-                                               "{} may not live long enough",
-                                               labeled_user_string);
+                let mut err = struct_span_err!(
+                    self.tcx.sess,
+                    span,
+                    E0310,
+                    "{} may not live long enough",
+                    labeled_user_string
+                );
                 binding_suggestion(&mut err, type_param_span, bound_kind, "'static");
                 err
             }
 
             _ => {
                 // If not, be less specific.
-                let mut err = struct_span_err!(self.tcx.sess,
-                                               span,
-                                               E0311,
-                                               "{} may not live long enough",
-                                               labeled_user_string);
-                err.help(&format!("consider adding an explicit lifetime bound for `{}`",
-                                  bound_kind));
+                let mut err = struct_span_err!(
+                    self.tcx.sess,
+                    span,
+                    E0311,
+                    "{} may not live long enough",
+                    labeled_user_string
+                );
+                err.help(&format!(
+                    "consider adding an explicit lifetime bound for `{}`",
+                    bound_kind
+                ));
                 self.tcx.note_and_explain_region(
                     region_scope_tree,
                     &mut err,
                     &format!("{} must be valid for ", labeled_user_string),
                     sub,
-                    "...");
+                    "...",
+                );
                 err
             }
         };
@@ -1061,26 +1147,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         err.emit();
     }
 
-    fn report_sub_sup_conflict(&self,
-                               region_scope_tree: &region::ScopeTree,
-                               var_origin: RegionVariableOrigin,
-                               sub_origin: SubregionOrigin<'tcx>,
-                               sub_region: Region<'tcx>,
-                               sup_origin: SubregionOrigin<'tcx>,
-                               sup_region: Region<'tcx>) {
-
+    fn report_sub_sup_conflict(
+        &self,
+        region_scope_tree: &region::ScopeTree,
+        var_origin: RegionVariableOrigin,
+        sub_origin: SubregionOrigin<'tcx>,
+        sub_region: Region<'tcx>,
+        sup_origin: SubregionOrigin<'tcx>,
+        sup_region: Region<'tcx>,
+    ) {
         let mut err = self.report_inference_failure(var_origin);
 
-        self.tcx.note_and_explain_region(region_scope_tree, &mut err,
+        self.tcx.note_and_explain_region(
+            region_scope_tree,
+            &mut err,
             "first, the lifetime cannot outlive ",
             sup_region,
-            "...");
+            "...",
+        );
 
         match (&sup_origin, &sub_origin) {
             (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) => {
-                if let (Some((sup_expected, sup_found)),
-                        Some((sub_expected, sub_found))) = (self.values_str(&sup_trace.values),
-                                                            self.values_str(&sub_trace.values)) {
+                if let (Some((sup_expected, sup_found)), Some((sub_expected, sub_found))) = (
+                    self.values_str(&sup_trace.values),
+                    self.values_str(&sub_trace.values),
+                ) {
                     if sub_expected == sup_expected && sub_found == sup_found {
                         self.tcx.note_and_explain_region(
                             region_scope_tree,
@@ -1089,10 +1180,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             sub_region,
                             "...",
                         );
-                        err.note(&format!("...so that the {}:\nexpected {}\n   found {}",
-                                          sup_trace.cause.as_requirement_str(),
-                                          sup_expected.content(),
-                                          sup_found.content()));
+                        err.note(&format!(
+                            "...so that the {}:\nexpected {}\n   found {}",
+                            sup_trace.cause.as_requirement_str(),
+                            sup_expected.content(),
+                            sup_found.content()
+                        ));
                         err.emit();
                         return;
                     }
@@ -1103,10 +1196,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 
         self.note_region_origin(&mut err, &sup_origin);
 
-        self.tcx.note_and_explain_region(region_scope_tree, &mut err,
+        self.tcx.note_and_explain_region(
+            region_scope_tree,
+            &mut err,
             "but, the lifetime must be valid for ",
             sub_region,
-            "...");
+            "...",
+        );
 
         self.note_region_origin(&mut err, &sub_origin);
         err.emit();
@@ -1114,9 +1210,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 }
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    fn report_inference_failure(&self,
-                                var_origin: RegionVariableOrigin)
-                                -> DiagnosticBuilder<'tcx> {
+    fn report_inference_failure(
+        &self,
+        var_origin: RegionVariableOrigin,
+    ) -> DiagnosticBuilder<'tcx> {
         let br_string = |br: ty::BoundRegion| {
             let mut s = br.to_string();
             if !s.is_empty() {
@@ -1131,23 +1228,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             infer::Autoref(_) => " for autoref".to_string(),
             infer::Coercion(_) => " for automatic coercion".to_string(),
             infer::LateBoundRegion(_, br, infer::FnCall) => {
-                format!(" for lifetime parameter {}in function call",
-                        br_string(br))
+                format!(" for lifetime parameter {}in function call", br_string(br))
             }
             infer::LateBoundRegion(_, br, infer::HigherRankedType) => {
                 format!(" for lifetime parameter {}in generic type", br_string(br))
             }
-            infer::LateBoundRegion(_, br, infer::AssocTypeProjection(def_id)) => {
-                format!(" for lifetime parameter {}in trait containing associated type `{}`",
-                        br_string(br), self.tcx.associated_item(def_id).name)
-            }
-            infer::EarlyBoundRegion(_, name) => {
-                format!(" for lifetime parameter `{}`",
-                        name)
-            }
+            infer::LateBoundRegion(_, br, infer::AssocTypeProjection(def_id)) => format!(
+                " for lifetime parameter {}in trait containing associated type `{}`",
+                br_string(br),
+                self.tcx.associated_item(def_id).name
+            ),
+            infer::EarlyBoundRegion(_, name) => format!(" for lifetime parameter `{}`", name),
             infer::BoundRegionInCoherence(name) => {
-                format!(" for lifetime parameter `{}` in coherence check",
-                        name)
+                format!(" for lifetime parameter `{}` in coherence check", name)
             }
             infer::UpvarRegion(ref upvar_id, _) => {
                 let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id);
@@ -1157,10 +1250,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             infer::NLL(..) => bug!("NLL variable found in lexical phase"),
         };
 
-        struct_span_err!(self.tcx.sess, var_origin.span(), E0495,
-                  "cannot infer an appropriate lifetime{} \
-                   due to conflicting requirements",
-                  var_description)
+        struct_span_err!(
+            self.tcx.sess,
+            var_origin.span(),
+            E0495,
+            "cannot infer an appropriate lifetime{} \
+             due to conflicting requirements",
+            var_description
+        )
     }
 }
 
@@ -1178,7 +1275,7 @@ impl<'tcx> ObligationCause<'tcx> {
         match self.code {
             CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
             MatchExpressionArm { source, .. } => Error0308(match source {
-                hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types",
+                hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have incompatible types",
                 _ => "match arms have incompatible types",
             }),
             IfExpression => Error0308("if and else have incompatible types"),
@@ -1193,11 +1290,11 @@ impl<'tcx> ObligationCause<'tcx> {
             // say, also take a look at the error code, maybe we can
             // tailor to that.
             _ => match terr {
-                TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() =>
-                    Error0644("closure/generator type that references itself"),
-                _ =>
-                    Error0308("mismatched types"),
-            }
+                TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() => {
+                    Error0644("closure/generator type that references itself")
+                }
+                _ => Error0308("mismatched types"),
+            },
         }
     }
 
@@ -1207,7 +1304,7 @@ impl<'tcx> ObligationCause<'tcx> {
             CompareImplMethodObligation { .. } => "method type is compatible with trait",
             ExprAssignable => "expression is assignable",
             MatchExpressionArm { source, .. } => match source {
-                hir::MatchSource::IfLetDesugar{..} => "`if let` arms have compatible types",
+                hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
                 _ => "match arms have compatible types",
             },
             IfExpression => "if and else have compatible types",
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 182c9b75196..c6635d59154 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -16,7 +16,7 @@ use rustc::ty::{self, RegionKind};
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::sync::Lrc;
 
-use super::{MirBorrowckCtxt, Context};
+use super::{Context, MirBorrowckCtxt};
 use super::{InitializationRequiringAction, PrefixSet};
 use dataflow::{ActiveBorrows, BorrowData, FlowAtLocation, MovingOutStatements};
 use dataflow::move_paths::MovePathIndex;
@@ -96,7 +96,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         } else {
                             true
                         }
-                    },
+                    }
                     _ => true,
                 };
 
@@ -106,9 +106,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         None => "value".to_owned(),
                     };
 
-                    err.note(&format!("move occurs because {} has type `{}`, \
-                                       which does not implement the `Copy` trait",
-                                       note_msg, ty));
+                    err.note(&format!(
+                        "move occurs because {} has type `{}`, \
+                         which does not implement the `Copy` trait",
+                        note_msg, ty
+                    ));
                 }
             }
 
@@ -154,7 +156,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             span,
             &self.describe_place(place).unwrap_or("_".to_owned()),
             self.retrieve_borrow_span(borrow),
-            &self.describe_place(&borrow.borrowed_place).unwrap_or("_".to_owned()),
+            &self.describe_place(&borrow.borrowed_place)
+                .unwrap_or("_".to_owned()),
             Origin::Mir,
         );
 
@@ -175,8 +178,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         use rustc::hir::ExprClosure;
         use rustc::mir::AggregateKind;
 
-        let local = match self.mir[location.block].statements.get(location.statement_index) {
-            Some(&Statement { kind: StatementKind::Assign(Place::Local(local), _), .. }) => local,
+        let local = match self.mir[location.block]
+            .statements
+            .get(location.statement_index)
+        {
+            Some(&Statement {
+                kind: StatementKind::Assign(Place::Local(local), _),
+                ..
+            }) => local,
             _ => return None,
         };
 
@@ -202,8 +211,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                             .with_freevars(node_id, |freevars| {
                                 for (v, place) in freevars.iter().zip(places) {
                                     match *place {
-                                        Operand::Copy(Place::Local(l)) |
-                                        Operand::Move(Place::Local(l)) if local == l =>
+                                        Operand::Copy(Place::Local(l))
+                                        | Operand::Move(Place::Local(l)) if local == l =>
                                         {
                                             debug!(
                                                 "find_closure_span: found captured local {:?}",
@@ -232,7 +241,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         context: Context,
         (place, span): (&Place<'tcx>, Span),
         gen_borrow_kind: BorrowKind,
-        issued_borrow: &BorrowData,
+        issued_borrow: &BorrowData<'tcx>,
         end_issued_loan_span: Option<Span>,
     ) {
         let issued_span = self.retrieve_borrow_span(issued_borrow);
@@ -255,8 +264,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             "immutable",
             "mutable",
         ) {
-            (BorrowKind::Shared, lft, _, BorrowKind::Mut { .. }, _, rgt) |
-            (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => self.tcx
+            (BorrowKind::Shared, lft, _, BorrowKind::Mut { .. }, _, rgt)
+            | (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => self.tcx
                 .cannot_reborrow_already_borrowed(
                     span,
                     &desc_place,
@@ -355,11 +364,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         context: Context,
         borrow: &BorrowData<'tcx>,
         drop_span: Span,
-        borrows: &ActiveBorrows<'cx, 'gcx, 'tcx>
+        borrows: &ActiveBorrows<'cx, 'gcx, 'tcx>,
     ) {
         let end_span = borrows.opt_region_end_span(&borrow.region);
         let scope_tree = borrows.0.scope_tree();
-        let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All).last().unwrap();
+        let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All)
+            .last()
+            .unwrap();
 
         let borrow_span = self.mir.source_info(borrow.location).span;
         let proper_span = match *root_place {
@@ -367,13 +378,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             _ => drop_span,
         };
 
-        if self.access_place_error_reported.contains(&(root_place.clone(), borrow_span)) {
-            debug!("suppressing access_place error when borrow doesn't live long enough for {:?}",
-                   borrow_span);
+        if self.access_place_error_reported
+            .contains(&(root_place.clone(), borrow_span))
+        {
+            debug!(
+                "suppressing access_place error when borrow doesn't live long enough for {:?}",
+                borrow_span
+            );
             return;
         }
 
-        self.access_place_error_reported.insert((root_place.clone(), borrow_span));
+        self.access_place_error_reported
+            .insert((root_place.clone(), borrow_span));
 
         match (borrow.region, &self.describe_place(&borrow.borrowed_place)) {
             (RegionKind::ReScope(_), Some(name)) => {
@@ -385,9 +401,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     drop_span,
                     borrow_span,
                     proper_span,
-                    end_span
+                    end_span,
                 );
-            },
+            }
             (RegionKind::ReScope(_), None) => {
                 self.report_scoped_temporary_value_does_not_live_long_enough(
                     context,
@@ -396,14 +412,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     drop_span,
                     borrow_span,
                     proper_span,
-                    end_span
+                    end_span,
                 );
-            },
-            (RegionKind::ReEarlyBound(_), Some(name)) |
-            (RegionKind::ReFree(_), Some(name)) |
-            (RegionKind::ReStatic, Some(name)) |
-            (RegionKind::ReEmpty, Some(name)) |
-            (RegionKind::ReVar(_), Some(name)) => {
+            }
+            (RegionKind::ReEarlyBound(_), Some(name))
+            | (RegionKind::ReFree(_), Some(name))
+            | (RegionKind::ReStatic, Some(name))
+            | (RegionKind::ReEmpty, Some(name))
+            | (RegionKind::ReVar(_), Some(name)) => {
                 self.report_unscoped_local_value_does_not_live_long_enough(
                     context,
                     name,
@@ -414,12 +430,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     proper_span,
                     end_span,
                 );
-            },
-            (RegionKind::ReEarlyBound(_), None) |
-            (RegionKind::ReFree(_), None) |
-            (RegionKind::ReStatic, None) |
-            (RegionKind::ReEmpty, None) |
-            (RegionKind::ReVar(_), None) => {
+            }
+            (RegionKind::ReEarlyBound(_), None)
+            | (RegionKind::ReFree(_), None)
+            | (RegionKind::ReStatic, None)
+            | (RegionKind::ReEmpty, None)
+            | (RegionKind::ReVar(_), None) => {
                 self.report_unscoped_temporary_value_does_not_live_long_enough(
                     context,
                     &scope_tree,
@@ -429,13 +445,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     proper_span,
                     end_span,
                 );
-            },
-            (RegionKind::ReLateBound(_, _), _) |
-            (RegionKind::ReSkolemized(_, _), _) |
-            (RegionKind::ReClosureBound(_), _) |
-            (RegionKind::ReErased, _) => {
+            }
+            (RegionKind::ReLateBound(_, _), _)
+            | (RegionKind::ReSkolemized(_, _), _)
+            | (RegionKind::ReClosureBound(_), _)
+            | (RegionKind::ReErased, _) => {
                 span_bug!(drop_span, "region does not make sense in this context");
-            },
+            }
         }
     }
 
@@ -450,11 +466,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         _proper_span: Span,
         end_span: Option<Span>,
     ) {
-        let mut err = self.tcx.path_does_not_live_long_enough(borrow_span,
-                                                              &format!("`{}`", name),
-                                                              Origin::Mir);
+        let mut err = self.tcx.path_does_not_live_long_enough(
+            borrow_span,
+            &format!("`{}`", name),
+            Origin::Mir,
+        );
         err.span_label(borrow_span, "borrowed value does not live long enough");
-        err.span_label(drop_span, format!("`{}` dropped here while still borrowed", name));
+        err.span_label(
+            drop_span,
+            format!("`{}` dropped here while still borrowed", name),
+        );
         if let Some(end) = end_span {
             err.span_label(end, "borrowed value needs to live until here");
         }
@@ -472,11 +493,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         proper_span: Span,
         end_span: Option<Span>,
     ) {
-        let mut err = self.tcx.path_does_not_live_long_enough(proper_span,
-                                                              "borrowed value",
-                                                              Origin::Mir);
+        let mut err =
+            self.tcx
+                .path_does_not_live_long_enough(proper_span, "borrowed value", Origin::Mir);
         err.span_label(proper_span, "temporary value does not live long enough");
-        err.span_label(drop_span, "temporary value dropped here while still borrowed");
+        err.span_label(
+            drop_span,
+            "temporary value dropped here while still borrowed",
+        );
         err.note("consider using a `let` binding to increase its lifetime");
         if let Some(end) = end_span {
             err.span_label(end, "temporary value needs to live until here");
@@ -496,14 +520,31 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         _proper_span: Span,
         _end_span: Option<Span>,
     ) {
-        let mut err = self.tcx.path_does_not_live_long_enough(borrow_span,
-                                                              &format!("`{}`", name),
-                                                              Origin::Mir);
+        debug!(
+            "report_unscoped_local_value_does_not_live_long_enough(\
+             {:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
+             )",
+            context, name, scope_tree, borrow, drop_span, borrow_span
+        );
+
+        let mut err = self.tcx.path_does_not_live_long_enough(
+            borrow_span,
+            &format!("`{}`", name),
+            Origin::Mir,
+        );
         err.span_label(borrow_span, "borrowed value does not live long enough");
         err.span_label(drop_span, "borrowed value only lives until here");
-        self.tcx.note_and_explain_region(scope_tree, &mut err,
-                                         "borrowed value must be valid for ",
-                                         borrow.region, "...");
+
+        if !self.tcx.sess.nll() {
+            self.tcx.note_and_explain_region(
+                scope_tree,
+                &mut err,
+                "borrowed value must be valid for ",
+                borrow.region,
+                "...",
+            );
+        }
+
         self.explain_why_borrow_contains_point(context, borrow, &mut err);
         err.emit();
     }
@@ -516,16 +557,31 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         drop_span: Span,
         _borrow_span: Span,
         proper_span: Span,
-        _end_span: Option<Span>
+        _end_span: Option<Span>,
     ) {
-        let mut err = self.tcx.path_does_not_live_long_enough(proper_span,
-                                                              "borrowed value",
-                                                              Origin::Mir);
+        debug!(
+            "report_unscoped_temporary_value_does_not_live_long_enough(\
+             {:?}, {:?}, {:?}, {:?}, {:?}\
+             )",
+            context, scope_tree, borrow, drop_span, proper_span
+        );
+
+        let mut err =
+            self.tcx
+                .path_does_not_live_long_enough(proper_span, "borrowed value", Origin::Mir);
         err.span_label(proper_span, "temporary value does not live long enough");
         err.span_label(drop_span, "temporary value only lives until here");
-        self.tcx.note_and_explain_region(scope_tree, &mut err,
-                                         "borrowed value must be valid for ",
-                                         borrow.region, "...");
+
+        if !self.tcx.sess.nll() {
+            self.tcx.note_and_explain_region(
+                scope_tree,
+                &mut err,
+                "borrowed value must be valid for ",
+                borrow.region,
+                "...",
+            );
+        }
+
         self.explain_why_borrow_contains_point(context, borrow, &mut err);
         err.emit();
     }
@@ -534,7 +590,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         &mut self,
         context: Context,
         (place, span): (&Place<'tcx>, Span),
-        loan: &BorrowData,
+        loan: &BorrowData<'tcx>,
     ) {
         let mut err = self.tcx.cannot_assign_to_borrowed(
             span,
@@ -706,9 +762,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 ProjectionElem::Field(_, field_type) => {
                     self.describe_field_from_ty(&field_type, field)
                 }
-                ProjectionElem::Index(..) |
-                ProjectionElem::ConstantIndex { .. } |
-                ProjectionElem::Subslice { .. } => {
+                ProjectionElem::Index(..)
+                | ProjectionElem::ConstantIndex { .. }
+                | ProjectionElem::Subslice { .. } => {
                     format!("{}", self.describe_field(&proj.base, field))
                 }
             },
@@ -765,13 +821,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             Place::Local(local) => {
                 let local = &self.mir.local_decls[*local];
                 Some(local.ty)
-            },
+            }
             Place::Static(ref st) => Some(st.ty),
-            Place::Projection(ref proj) => {
-                match proj.elem {
-                    ProjectionElem::Field(_, ty) => Some(ty),
-                    _ => None,
-                }
+            Place::Projection(ref proj) => match proj.elem {
+                ProjectionElem::Field(_, ty) => Some(ty),
+                _ => None,
             },
         }
     }
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index b6d8e14b747..19f95aeec70 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -21,7 +21,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     pub(in borrow_check) fn explain_why_borrow_contains_point(
         &self,
         context: Context,
-        borrow: &BorrowData<'_>,
+        borrow: &BorrowData<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
     ) {
         if let Some(regioncx) = &self.nonlexical_regioncx {
@@ -70,9 +70,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         }
                     }
 
-                    _ => {
-                        cause.label_diagnostic(mir, err);
+                    Cause::UniversalRegion(region_vid) => {
+                        if let Some(region) = regioncx.to_error_region(region_vid) {
+                            self.tcx.note_and_explain_free_region(
+                                err,
+                                "borrowed value must be valid for ",
+                                region,
+                                "...",
+                            );
+                        }
                     }
+
+                    _ => {}
                 }
             }
         }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 33c012dfad8..3ffb4370359 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -26,7 +26,6 @@ use rustc::ty::{self, RegionVid, Ty, TypeFoldable};
 use rustc::util::common::ErrorReported;
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_vec::IndexVec;
-use rustc_errors::DiagnosticBuilder;
 use std::fmt;
 use std::rc::Rc;
 use syntax::ast;
@@ -435,7 +434,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         self.check_type_tests(infcx, mir, mir_def_id, outlives_requirements.as_mut());
 
-        self.check_universal_regions(infcx, mir, mir_def_id, outlives_requirements.as_mut());
+        self.check_universal_regions(infcx, mir_def_id, outlives_requirements.as_mut());
 
         let outlives_requirements = outlives_requirements.unwrap_or(vec![]);
 
@@ -574,10 +573,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 // an error that multiple bounds are required.
                 tcx.sess.span_err(
                     type_test.span,
-                    &format!(
-                        "`{}` does not live long enough",
-                        type_test.generic_kind,
-                    ),
+                    &format!("`{}` does not live long enough", type_test.generic_kind,),
                 );
             }
         }
@@ -589,13 +585,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// existentially bound, then we check its inferred value and try
     /// to find a good name from that. Returns `None` if we can't find
     /// one (e.g., this is just some random part of the CFG).
-    fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
+    pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
         if self.universal_regions.is_universal_region(r) {
             return self.definitions[r].external_name;
         } else {
             let inferred_values = self.inferred_values
-                                      .as_ref()
-                                      .expect("region values not yet inferred");
+                .as_ref()
+                .expect("region values not yet inferred");
             let upper_bound = self.universal_upper_bound(r);
             if inferred_values.contains(r, upper_bound) {
                 self.to_error_region(upper_bound)
@@ -807,9 +803,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) -> bool {
         debug!(
             "eval_region_test(point={:?}, lower_bound={:?}, test={:?})",
-            point,
-            lower_bound,
-            test
+            point, lower_bound, test
         );
 
         match test {
@@ -841,9 +835,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) -> bool {
         debug!(
             "eval_outlives({:?}: {:?} @ {:?})",
-            sup_region,
-            sub_region,
-            point
+            sup_region, sub_region, point
         );
 
         // Roughly speaking, do a DFS of all region elements reachable
@@ -897,7 +889,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     fn check_universal_regions<'gcx>(
         &self,
         infcx: &InferCtxt<'_, 'gcx, 'tcx>,
-        mir: &Mir<'tcx>,
         mir_def_id: DefId,
         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'gcx>>>,
     ) {
@@ -913,7 +904,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         for (fr, _) in universal_definitions {
             self.check_universal_region(
                 infcx,
-                mir,
                 mir_def_id,
                 fr,
                 &mut propagated_outlives_requirements,
@@ -932,7 +922,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     fn check_universal_region<'gcx>(
         &self,
         infcx: &InferCtxt<'_, 'gcx, 'tcx>,
-        mir: &Mir<'tcx>,
         mir_def_id: DefId,
         longer_fr: RegionVid,
         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'gcx>>>,
@@ -951,8 +940,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
             debug!(
                 "check_universal_region: fr={:?} does not outlive shorter_fr={:?}",
-                longer_fr,
-                shorter_fr,
+                longer_fr, shorter_fr,
             );
 
             let blame_span = self.blame_span(longer_fr, shorter_fr);
@@ -990,7 +978,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             // Note: in this case, we use the unapproximated regions
             // to report the error. This gives better error messages
             // in some cases.
-            self.report_error(infcx, mir, mir_def_id, longer_fr, shorter_fr, blame_span);
+            self.report_error(infcx, mir_def_id, longer_fr, shorter_fr, blame_span);
         }
     }
 
@@ -1005,7 +993,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     fn report_error(
         &self,
         infcx: &InferCtxt<'_, '_, 'tcx>,
-        mir: &Mir<'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
         outlived_fr: RegionVid,
@@ -1039,12 +1026,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             &format!("{} does not outlive {}", fr_string, outlived_fr_string,),
         );
 
-        // Find out why `fr` had to outlive `outlived_fr`...
-        let inferred_values = self.inferred_values.as_ref().unwrap();
-        if let Some(cause) = inferred_values.cause(fr, outlived_fr) {
-            cause.label_diagnostic(mir, &mut diag);
-        }
-
         diag.emit();
     }
 
@@ -1134,10 +1115,7 @@ impl fmt::Debug for Constraint {
         write!(
             formatter,
             "({:?}: {:?} @ {:?}) due to {:?}",
-            self.sup,
-            self.sub,
-            self.point,
-            self.span
+            self.sup, self.sub, self.point, self.span
         )
     }
 }
@@ -1187,9 +1165,7 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
 
         debug!(
             "apply_requirements(location={:?}, closure_def_id={:?}, closure_substs={:?})",
-            location,
-            closure_def_id,
-            closure_substs
+            location, closure_def_id, closure_substs
         );
 
         // Get Tu.
@@ -1217,9 +1193,7 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
                         "apply_requirements: region={:?} \
                          outlived_region={:?} \
                          outlives_requirement={:?}",
-                        region,
-                        outlived_region,
-                        outlives_requirement,
+                        region, outlived_region, outlives_requirement,
                     );
                     infcx.sub_regions(origin, outlived_region, region);
                 }
@@ -1230,9 +1204,7 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
                         "apply_requirements: ty={:?} \
                          outlived_region={:?} \
                          outlives_requirement={:?}",
-                        ty,
-                        outlived_region,
-                        outlives_requirement,
+                        ty, outlived_region, outlives_requirement,
                     );
                     infcx.register_region_obligation(
                         body_id,
@@ -1285,77 +1257,14 @@ impl CauseExt for Rc<Cause> {
 }
 
 impl Cause {
-    pub(crate) fn label_diagnostic(&self, mir: &Mir<'_>, diag: &mut DiagnosticBuilder<'_>) {
-        // The cause information is pretty messy. Only dump it as an
-        // internal debugging aid if -Znll-dump-cause is given.
-        let nll_dump_cause = ty::tls::with(|tcx| tcx.sess.nll_dump_cause());
-        if !nll_dump_cause {
-            return;
-        }
-
-        let mut string = String::new();
-        self.push_diagnostic_string(mir, &mut string);
-        diag.note(&string);
-    }
-
-    fn push_diagnostic_string(&self, mir: &Mir<'_>, string: &mut String) {
-        match self {
-            Cause::LiveVar(local, location) => {
-                string.push_str(&format!("because `{:?}` is live at {:?}", local, location));
-            }
-
-            Cause::DropVar(local, location) => {
-                string.push_str(&format!(
-                    "because `{:?}` is dropped at {:?}",
-                    local,
-                    location
-                ));
-            }
-
-            Cause::LiveOther(location) => {
-                string.push_str(&format!(
-                    "because of a general liveness constraint at {:?}",
-                    location
-                ));
-            }
-
-            Cause::UniversalRegion(region_vid) => {
-                string.push_str(&format!(
-                    "because `{:?}` is universally quantified",
-                    region_vid
-                ));
-            }
-
-            Cause::Outlives {
-                original_cause,
-                constraint_location,
-                constraint_span: _,
-            } => {
-                string.push_str(&format!(
-                    "because of an outlives relation created at `{:?}`\n",
-                    constraint_location
-                ));
-
-                original_cause.push_diagnostic_string(mir, string);
-            }
-        }
-    }
-
     pub(crate) fn root_cause(&self) -> &Cause {
         match self {
-            Cause::LiveVar(..) |
-            Cause::DropVar(..) |
-            Cause::LiveOther(..) |
-            Cause::UniversalRegion(..) => {
-                self
-            }
+            Cause::LiveVar(..)
+            | Cause::DropVar(..)
+            | Cause::LiveOther(..)
+            | Cause::UniversalRegion(..) => self,
 
-            Cause::Outlives {
-                original_cause,
-                ..
-            } => {
-                original_cause.root_cause()
-            }
+            Cause::Outlives { original_cause, .. } => original_cause.root_cause(),
         }
     }
 }
diff --git a/src/test/ui/nll/borrowed-local-error.rs b/src/test/ui/nll/borrowed-local-error.rs
new file mode 100644
index 00000000000..785a38da959
--- /dev/null
+++ b/src/test/ui/nll/borrowed-local-error.rs
@@ -0,0 +1,26 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Znll-dump-cause
+
+#![feature(nll)]
+
+fn gimme(x: &(u32,)) -> &u32 {
+    &x.0
+}
+
+fn main() {
+    let x = gimme({
+        let v = (22,);
+        &v
+        //~^ ERROR `v` does not live long enough [E0597]
+    });
+    println!("{:?}", x);
+}
diff --git a/src/test/ui/nll/borrowed-local-error.stderr b/src/test/ui/nll/borrowed-local-error.stderr
new file mode 100644
index 00000000000..3bc19785548
--- /dev/null
+++ b/src/test/ui/nll/borrowed-local-error.stderr
@@ -0,0 +1,17 @@
+error[E0597]: `v` does not live long enough
+  --> $DIR/borrowed-local-error.rs:22:9
+   |
+LL |       let x = gimme({
+   |  _____________-
+LL | |         let v = (22,);
+LL | |         &v
+   | |         ^^ borrowed value does not live long enough
+LL | |         //~^ ERROR `v` does not live long enough [E0597]
+LL | |     });
+   | |_____-- borrow later used here
+   |       |
+   |       borrowed value only lives until here
+
+error: aborting due to previous error
+
+If you want more information on this error, try using "rustc --explain E0597"
diff --git a/src/test/ui/nll/borrowed-temporary-error.rs b/src/test/ui/nll/borrowed-temporary-error.rs
new file mode 100644
index 00000000000..e1a6112d173
--- /dev/null
+++ b/src/test/ui/nll/borrowed-temporary-error.rs
@@ -0,0 +1,26 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Znll-dump-cause
+
+#![feature(nll)]
+
+fn gimme(x: &(u32,)) -> &u32 {
+    &x.0
+}
+
+fn main() {
+    let x = gimme({
+        let v = 22;
+        &(v,)
+        //~^ ERROR borrowed value does not live long enough [E0597]
+    });
+    println!("{:?}", x);
+}
diff --git a/src/test/ui/nll/borrowed-temporary-error.stderr b/src/test/ui/nll/borrowed-temporary-error.stderr
new file mode 100644
index 00000000000..f5cb1dccc37
--- /dev/null
+++ b/src/test/ui/nll/borrowed-temporary-error.stderr
@@ -0,0 +1,14 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/borrowed-temporary-error.rs:22:10
+   |
+LL |         &(v,)
+   |          ^^^^ temporary value does not live long enough
+LL |         //~^ ERROR borrowed value does not live long enough [E0597]
+LL |     });
+   |       - temporary value only lives until here
+LL |     println!("{:?}", x);
+   |                      - borrow later used here
+
+error: aborting due to previous error
+
+If you want more information on this error, try using "rustc --explain E0597"
diff --git a/src/test/ui/nll/borrowed-universal-error-2.rs b/src/test/ui/nll/borrowed-universal-error-2.rs
new file mode 100644
index 00000000000..da03a9fc39b
--- /dev/null
+++ b/src/test/ui/nll/borrowed-universal-error-2.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Znll-dump-cause
+
+#![feature(nll)]
+#![allow(warnings)]
+
+fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
+    let v = 22;
+    &v
+    //~^ ERROR `v` does not live long enough [E0597]
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/borrowed-universal-error-2.stderr b/src/test/ui/nll/borrowed-universal-error-2.stderr
new file mode 100644
index 00000000000..ff999a71e0f
--- /dev/null
+++ b/src/test/ui/nll/borrowed-universal-error-2.stderr
@@ -0,0 +1,18 @@
+error[E0597]: `v` does not live long enough
+  --> $DIR/borrowed-universal-error-2.rs:18:5
+   |
+LL |     &v
+   |     ^^ borrowed value does not live long enough
+LL |     //~^ ERROR `v` does not live long enough [E0597]
+LL | }
+   | - borrowed value only lives until here
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 16:1...
+  --> $DIR/borrowed-universal-error-2.rs:16:1
+   |
+LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+If you want more information on this error, try using "rustc --explain E0597"
diff --git a/src/test/ui/nll/borrowed-universal-error.rs b/src/test/ui/nll/borrowed-universal-error.rs
new file mode 100644
index 00000000000..fdc4c29071e
--- /dev/null
+++ b/src/test/ui/nll/borrowed-universal-error.rs
@@ -0,0 +1,26 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Znll-dump-cause
+
+#![feature(nll)]
+#![allow(warnings)]
+
+fn gimme(x: &(u32,)) -> &u32 {
+    &x.0
+}
+
+fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
+    let v = 22;
+    gimme(&(v,))
+    //~^ ERROR borrowed value does not live long enough [E0597]
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/borrowed-universal-error.stderr b/src/test/ui/nll/borrowed-universal-error.stderr
new file mode 100644
index 00000000000..4a3d0c6d959
--- /dev/null
+++ b/src/test/ui/nll/borrowed-universal-error.stderr
@@ -0,0 +1,18 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/borrowed-universal-error.rs:22:12
+   |
+LL |     gimme(&(v,))
+   |            ^^^^ temporary value does not live long enough
+LL |     //~^ ERROR borrowed value does not live long enough [E0597]
+LL | }
+   | - temporary value only lives until here
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 20:1...
+  --> $DIR/borrowed-universal-error.rs:20:1
+   |
+LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+If you want more information on this error, try using "rustc --explain E0597"
diff --git a/src/test/ui/nll/capture-ref-in-struct.stderr b/src/test/ui/nll/capture-ref-in-struct.stderr
index 316a918e4ee..1c545906893 100644
--- a/src/test/ui/nll/capture-ref-in-struct.stderr
+++ b/src/test/ui/nll/capture-ref-in-struct.stderr
@@ -9,8 +9,6 @@ LL |     }
 LL | 
 LL |     deref(p);
    |           - borrow later used here
-   |
-   = note: borrowed value must be valid for lifetime '_#5r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr
index 93a7bab3386..18ffdc58349 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr
@@ -34,8 +34,6 @@ LL |     }
 LL | 
 LL |     deref(p);
    |           - borrow later used here
-   |
-   = note: borrowed value must be valid for lifetime '_#6r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
index b6c1d808ff5..7b2b2f74872 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
@@ -61,8 +61,6 @@ LL |       }
 LL | 
 LL |       deref(p);
    |             - borrow later used here
-   |
-   = note: borrowed value must be valid for lifetime '_#4r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
index 3cb6524f3b4..0a45603a42c 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
@@ -38,8 +38,6 @@ LL |     }
 LL | 
 LL |     deref(p);
    |           - borrow later used here
-   |
-   = note: borrowed value must be valid for lifetime '_#4r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index eb4d264bf82..21ed421fe96 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -78,8 +78,6 @@ LL |     let cell = Cell::new(&a);
 ...
 LL | }
    | - borrowed value only lives until here
-   |
-   = note: borrowed value must be valid for lifetime '_#2r...
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.stderr
index f7e85e4277b..c77e0772ce9 100644
--- a/src/test/ui/nll/return-ref-mut-issue-46557.stderr
+++ b/src/test/ui/nll/return-ref-mut-issue-46557.stderr
@@ -6,8 +6,6 @@ LL |     let ref mut x = 1234543; //~ ERROR borrowed value does not live long en
 LL |     x
 LL | }
    | - temporary value only lives until here
-   |
-   = note: borrowed value must be valid for lifetime '_#2r...
 
 error: aborting due to previous error