]> git.lizzy.rs Git - rust.git/commitdiff
refactor the `pat_is_catchall` logic
authorAriel Ben-Yehuda <ariel.byd@gmail.com>
Sat, 24 Sep 2016 15:23:46 +0000 (18:23 +0300)
committerAriel Ben-Yehuda <ariel.byd@gmail.com>
Wed, 26 Oct 2016 19:41:17 +0000 (22:41 +0300)
src/librustc_const_eval/check_match.rs

index f8ac841a0a265c7b919eb0abcc11565de8a50ec1..7878ffff48d3b314ce36faf7d9c9f22c51cb9786 100644 (file)
@@ -74,21 +74,6 @@ fn as_raw(self) -> &'a Pat {
         return pat;
     }
 
-
-    /// Checks for common cases of "catchall" patterns that may not be intended as such.
-    fn is_catchall(self, dm: &DefMap) -> bool {
-        fn is_catchall(dm: &DefMap, pat: &Pat) -> bool {
-            match pat.node {
-                PatKind::Binding(.., None) => true,
-                PatKind::Binding(.., Some(ref s)) => is_catchall(dm, s),
-                PatKind::Ref(ref s, _) => is_catchall(dm, s),
-                PatKind::Tuple(ref v, _) => v.iter().all(|p|is_catchall(dm, &p)),
-                _ => false
-            }
-        }
-        is_catchall(dm, self.pat)
-    }
-
     fn span(self) -> Span {
         self.pat.span
     }
@@ -339,11 +324,25 @@ fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
     });
 }
 
+/// Checks for common cases of "catchall" patterns that may not be intended as such.
+fn pat_is_catchall(dm: &DefMap, pat: &Pat) -> bool {
+    match pat.node {
+        PatKind::Binding(.., None) => true,
+        PatKind::Binding(.., Some(ref s)) => pat_is_catchall(dm, s),
+        PatKind::Ref(ref s, _) => pat_is_catchall(dm, s),
+        PatKind::Tuple(ref v, _) => v.iter().all(|p| {
+            pat_is_catchall(dm, &p)
+        }),
+        _ => false
+    }
+}
+
 // Check for unreachable patterns
 fn check_arms(cx: &MatchCheckCtxt,
               arms: &[(Vec<P<Pat>>, Option<&hir::Expr>)],
               source: hir::MatchSource) {
     let mut seen = Matrix(vec![]);
+    let mut catchall = None;
     let mut printed_if_let_err = false;
     for &(ref pats, guard) in arms {
         for pat in pats {
@@ -393,11 +392,8 @@ fn check_arms(cx: &MatchCheckCtxt,
                                                            "unreachable pattern");
                             err.span_label(pat.span, &format!("this is an unreachable pattern"));
                             // if we had a catchall pattern, hint at that
-                            for row in &seen.0 {
-                                if row[0].is_catchall(&cx.tcx.def_map.borrow()) {
-                                    span_note!(err, row[0].span(),
-                                               "this pattern matches any value");
-                                }
+                            if let Some(catchall) = catchall {
+                                err.span_note(catchall, "this pattern matches any value");
                             }
                             err.emit();
                         },
@@ -414,6 +410,10 @@ fn check_arms(cx: &MatchCheckCtxt,
                 let Matrix(mut rows) = seen;
                 rows.push(v);
                 seen = Matrix(rows);
+                if catchall.is_none() && pat_is_catchall(&cx.tcx.def_map.borrow(), pat) {
+                    catchall = Some(pat.span);
+                }
+
             }
         }
     }