about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2017-12-10 21:15:52 +0000
committerDavid Wood <david@davidtw.co>2017-12-11 22:20:12 +0000
commit00c7a3f4dce52caad94decd820e8cd66a30b3d8d (patch)
tree0adaa312c68148caa3266aae8e204cdede78d8bc /src
parentbaf68d3a3756b040aae2028f8d5a7a0a239458ef (diff)
downloadrust-00c7a3f4dce52caad94decd820e8cd66a30b3d8d.tar.gz
rust-00c7a3f4dce52caad94decd820e8cd66a30b3d8d.zip
Refactored and tidied up report function
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs145
1 files changed, 92 insertions, 53 deletions
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index a8feaa9ca94..186598001da 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -9,11 +9,14 @@
 // except according to those terms.
 
 use syntax_pos::Span;
+use rustc::middle::region::ScopeTree;
 use rustc::mir::{BorrowKind, Field, Local, Location, Operand};
 use rustc::mir::{Place, ProjectionElem, Rvalue, StatementKind};
 use rustc::ty::{self, RegionKind};
 use rustc_data_structures::indexed_vec::Idx;
 
+use std::rc::Rc;
+
 use super::{MirBorrowckCtxt, Context};
 use super::{InitializationRequiringAction, PrefixSet};
 use dataflow::{BorrowData, Borrows, FlowAtLocation, MovingOutStatements};
@@ -354,64 +357,100 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             _ => drop_span,
         };
 
-        match &self.describe_place(&borrow.place) {
-            Some(description) => {
-                match borrow.region {
-                    RegionKind::ReScope(_) => {
-                        let mut err = self.tcx.path_does_not_live_long_enough(
-                            drop_span, &format!("`{}`", description), Origin::Mir);
-                        err.span_label(borrow_span, "borrow occurs here");
-                        err.span_label(drop_span,
-                                       format!("`{}` dropped here while still borrowed",
-                                               description));
-                        if let Some(end) = end_span {
-                            err.span_label(end, "borrowed value needs to live until here");
-                        }
-                        err.emit();
-                    },
-                    _ => {
-                        let mut err = self.tcx.path_does_not_live_long_enough(
-                            borrow_span, &format!("`{}`", description), Origin::Mir);
-                        err.span_label(borrow_span, "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, "...");
-                        err.emit();
-                    }
-                }
+        match (borrow.region, &self.describe_place(&borrow.place)) {
+            (RegionKind::ReScope(_), Some(name)) => {
+                self.report_scoped_local_value_does_not_live_long_enough(
+                    name, &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
             },
-            None => {
-                match borrow.region {
-                    RegionKind::ReEarlyBound(_) | RegionKind::ReFree(_) => {
-                        let mut err = self.tcx.path_does_not_live_long_enough(proper_span,
-                                                                              "borrowed value",
-                                                                              Origin::Mir);
-                        err.span_label(proper_span, "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, "...");
-                        err.emit();
-                    },
-                    _ => {
-                        let mut err = self.tcx.path_does_not_live_long_enough(drop_span,
-                                                                              "borrowed value",
-                                                                              Origin::Mir);
-                        err.span_label(proper_span, "temporary value created here");
-                        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");
-                        }
-                        err.emit();
-                    },
-                }
+            (RegionKind::ReScope(_), None) => {
+                self.report_scoped_temporary_value_does_not_live_long_enough(
+                    &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
+            },
+            (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(
+                    name, &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
+            },
+            (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(
+                    &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
+            },
+            (RegionKind::ReLateBound(_, _), _) |
+            (RegionKind::ReSkolemized(_, _), _) |
+            (RegionKind::ReErased, _) => {
+                span_bug!(drop_span, "region does not make sense in this context");
             },
         }
     }
 
+    fn report_scoped_local_value_does_not_live_long_enough(
+        &mut self, name: &String, _scope_tree: &Rc<ScopeTree>, _borrow: &BorrowData<'tcx>,
+        drop_span: Span, borrow_span: Span, _proper_span: Span, end_span: Option<Span>
+    ) {
+        let mut err = self.tcx.path_does_not_live_long_enough(drop_span,
+                                                              &format!("`{}`", name),
+                                                              Origin::Mir);
+        err.span_label(borrow_span, "borrow occurs here");
+        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");
+        }
+        err.emit();
+    }
+
+    fn report_scoped_temporary_value_does_not_live_long_enough(
+        &mut self, _scope_tree: &Rc<ScopeTree>, _borrow: &BorrowData<'tcx>,
+        drop_span: Span, borrow_span: Span, proper_span: Span, end_span: Option<Span>
+    ) {
+        let mut err = self.tcx.path_does_not_live_long_enough(borrow_span,
+                                                              "borrowed value",
+                                                              Origin::Mir);
+        err.span_label(proper_span, "temporary value created here");
+        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");
+        }
+        err.emit();
+    }
+
+    fn report_unscoped_local_value_does_not_live_long_enough(
+        &mut self, name: &String, scope_tree: &Rc<ScopeTree>, borrow: &BorrowData<'tcx>,
+        drop_span: Span, borrow_span: Span, _proper_span: Span, _end_span: Option<Span>
+    ) {
+        let mut err = self.tcx.path_does_not_live_long_enough(borrow_span,
+                                                              &format!("`{}`", name),
+                                                              Origin::Mir);
+        err.span_label(borrow_span, "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, "...");
+        err.emit();
+    }
+
+    fn report_unscoped_temporary_value_does_not_live_long_enough(
+        &mut self, scope_tree: &Rc<ScopeTree>, borrow: &BorrowData<'tcx>,
+        drop_span: Span, _borrow_span: Span, proper_span: Span, _end_span: Option<Span>
+    ) {
+        let mut err = self.tcx.path_does_not_live_long_enough(proper_span,
+                                                              "borrowed value",
+                                                              Origin::Mir);
+        err.span_label(proper_span, "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, "...");
+        err.emit();
+    }
+
     pub(super) fn report_illegal_mutation_of_borrowed(
         &mut self,
         _: Context,