]> git.lizzy.rs Git - rust.git/commitdiff
Simplified closure handling to need no new cosntraint categories.
authorDavid Wood <david@davidtw.co>
Mon, 23 Jul 2018 11:07:11 +0000 (13:07 +0200)
committerDavid Wood <david@davidtw.co>
Fri, 27 Jul 2018 09:18:07 +0000 (11:18 +0200)
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs

index 1b540ef74be49e05830e28c9635e08e96cdba54b..836eaa23f68534cf6544550d4309c290f8d009f1 100644 (file)
@@ -31,9 +31,7 @@
 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 @@ fn constraint_is_interesting(&self, index: ConstraintIndex) -> bool {
             "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 @@ pub(super) fn report_error(
             }
         }
 
-        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 @@ fn report_closure_error(
             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 @@ fn report_general_error(
         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 @@ fn report_general_error(
         );
 
         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);
     }