about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2018-07-23 13:07:11 +0200
committerDavid Wood <david@davidtw.co>2018-07-27 11:18:07 +0200
commit41ce2e9dd29eecdf4a4d7249cac3c0d631a0cdd6 (patch)
tree98daabd738ce742661816abafae0473481434113
parent3d0e93309d61636585cfe5ac75c0db8cb5ba03e1 (diff)
downloadrust-41ce2e9dd29eecdf4a4d7249cac3c0d631a0cdd6.tar.gz
rust-41ce2e9dd29eecdf4a4d7249cac3c0d631a0cdd6.zip
Simplified closure handling to need no new cosntraint categories.
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs112
1 files changed, 45 insertions, 67 deletions
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index 1b540ef74be..836eaa23f68 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -31,9 +31,7 @@ mod var_name;
 enum ConstraintCategory {
     Cast,
     Assignment,
-    AssignmentToUpvar,
     Return,
-    CallArgumentToUpvar,
     CallArgument,
     Other,
     Boring,
@@ -42,14 +40,10 @@ enum ConstraintCategory {
 impl fmt::Display for ConstraintCategory {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            ConstraintCategory::Assignment | ConstraintCategory::AssignmentToUpvar => {
-                write!(f, "assignment")
-            }
+            ConstraintCategory::Assignment => write!(f, "assignment"),
             ConstraintCategory::Return => write!(f, "return"),
             ConstraintCategory::Cast => write!(f, "cast"),
-            ConstraintCategory::CallArgument | ConstraintCategory::CallArgumentToUpvar => {
-                write!(f, "argument")
-            }
+            ConstraintCategory::CallArgument => write!(f, "argument"),
             _ => write!(f, "free region"),
         }
     }
@@ -224,10 +218,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             "constraint_is_interesting: locations={:?} constraint={:?}",
             constraint.locations, constraint
         );
-        if let Locations::Interesting(_) = constraint.locations {
-            true
-        } else {
-            false
+
+        match constraint.locations {
+            Locations::Interesting(_) | Locations::All => true,
+            _ => false,
         }
     }
 
@@ -320,45 +314,25 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
         }
 
-        let category = match (
-            category,
+        let (fr_is_local, outlived_fr_is_local): (bool, bool) = (
             self.universal_regions.is_local_free_region(fr),
             self.universal_regions.is_local_free_region(outlived_fr),
-        ) {
-            (ConstraintCategory::Assignment, true, false) => ConstraintCategory::AssignmentToUpvar,
-            (ConstraintCategory::CallArgument, true, false) => {
-                ConstraintCategory::CallArgumentToUpvar
-            }
-            (category, _, _) => category,
+        );
+        debug!("report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}",
+               fr_is_local, outlived_fr_is_local, category);
+
+        match (fr_is_local, outlived_fr_is_local) {
+            (true, false) =>
+                self.report_escapes_closure_error(mir, infcx, mir_def_id, fr, outlived_fr,
+                                                  category, span, errors_buffer),
+            _ =>
+                self.report_general_error(mir, infcx, mir_def_id, fr, fr_is_local,
+                                          outlived_fr, outlived_fr_is_local,
+                                          category, span, errors_buffer),
         };
-
-        debug!("report_error: category={:?}", category);
-        match category {
-            ConstraintCategory::AssignmentToUpvar | ConstraintCategory::CallArgumentToUpvar => self
-                .report_closure_error(
-                    mir,
-                    infcx,
-                    mir_def_id,
-                    fr,
-                    outlived_fr,
-                    category,
-                    span,
-                    errors_buffer,
-                ),
-            _ => self.report_general_error(
-                mir,
-                infcx,
-                mir_def_id,
-                fr,
-                outlived_fr,
-                category,
-                span,
-                errors_buffer,
-            ),
-        }
     }
 
-    fn report_closure_error(
+    fn report_escapes_closure_error(
         &self,
         mir: &Mir<'tcx>,
         infcx: &InferCtxt<'_, '_, 'tcx>,
@@ -374,16 +348,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             self.get_var_name_and_span_for_region(infcx.tcx, mir, outlived_fr);
 
         if fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none() {
-            return self.report_general_error(
-                mir,
-                infcx,
-                mir_def_id,
-                fr,
-                outlived_fr,
-                category,
-                span,
-                errors_buffer,
-            );
+            return self.report_general_error(mir, infcx, mir_def_id,
+                                             fr, true, outlived_fr, false,
+                                             category, span, errors_buffer);
         }
 
         let mut diag = infcx
@@ -423,7 +390,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         infcx: &InferCtxt<'_, '_, 'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
+        fr_is_local: bool,
         outlived_fr: RegionVid,
+        outlived_fr_is_local: bool,
         category: ConstraintCategory,
         span: Span,
         errors_buffer: &mut Vec<Diagnostic>,
@@ -434,17 +403,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         );
 
         let counter = &mut 1;
-        let fr_name = self.give_region_a_name(infcx.tcx, mir, mir_def_id, fr, counter, &mut diag);
-        let outlived_fr_name =
-            self.give_region_a_name(infcx.tcx, mir, mir_def_id, outlived_fr, counter, &mut diag);
-
-        diag.span_label(
-            span,
-            format!(
-                "{} requires that `{}` must outlive `{}`",
-                category, fr_name, outlived_fr_name,
-            ),
-        );
+        let fr_name = self.give_region_a_name(
+            infcx.tcx, mir, mir_def_id, fr, counter, &mut diag);
+        let outlived_fr_name = self.give_region_a_name(
+            infcx.tcx, mir, mir_def_id, outlived_fr, counter, &mut diag);
+
+        match (category, outlived_fr_is_local, fr_is_local) {
+            (ConstraintCategory::Return, true, _) => {
+                diag.span_label(span, format!(
+                    "closure was supposed to return data with lifetime `{}` but it is returning \
+                    data with lifetime `{}`",
+                    fr_name, outlived_fr_name,
+                ));
+            },
+            _ => {
+                diag.span_label(span, format!(
+                    "{} requires that `{}` must outlive `{}`",
+                    category, fr_name, outlived_fr_name,
+                ));
+            },
+        }
 
         diag.buffer(errors_buffer);
     }