]> git.lizzy.rs Git - rust.git/commitdiff
improve robustness of pat walkers
authorMazdak Farrokhzad <twingoow@gmail.com>
Sat, 14 Dec 2019 22:43:21 +0000 (23:43 +0100)
committerMazdak Farrokhzad <twingoow@gmail.com>
Mon, 23 Dec 2019 13:47:19 +0000 (14:47 +0100)
src/librustc/hir/mod.rs
src/librustc/hir/pat_util.rs
src/librustc_mir/hair/pattern/check_match.rs

index 4aa8c12a219cabeed5740044c452278b1ad73ca1..a85685caf7d7a01642ea70dad8497bbf2f082c1a 100644 (file)
@@ -921,6 +921,16 @@ fn walk_(&self, it: &mut impl FnMut(&Pat) -> bool) {
     pub fn walk(&self, mut it: impl FnMut(&Pat) -> bool) {
         self.walk_(&mut it)
     }
+
+    /// Walk the pattern in left-to-right order.
+    ///
+    /// If you always want to recurse, prefer this method over `walk`.
+    pub fn walk_always(&self, mut it: impl FnMut(&Pat)) {
+        self.walk(|p| {
+            it(p);
+            true
+        })
+    }
 }
 
 /// A single field in a struct pattern.
index c0aa54beac2759239443c23d882259eed9c33a0b..8d3b464a8ffa1e6d67d71559dfabe53eaa83f58b 100644 (file)
@@ -79,11 +79,10 @@ pub fn is_refutable(&self) -> bool {
     /// Call `f` on every "binding" in a pattern, e.g., on `a` in
     /// `match foo() { Some(a) => (), None => () }`
     pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident)) {
-        self.walk(|p| {
+        self.walk_always(|p| {
             if let PatKind::Binding(binding_mode, _, ident, _) = p.kind {
                 f(binding_mode, p.hir_id, p.span, ident);
             }
-            true
         });
     }
 
index 3cfafaf180634e9cf7b128d0b46c99d32564ca78..30501e4504dcc7c98c6ac36d4215872e6e70eac9 100644 (file)
@@ -269,7 +269,7 @@ fn const_not_var(err: &mut DiagnosticBuilder<'_>, tcx: TyCtxt<'_>, pat: &Pat, pa
 }
 
 fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
-    pat.walk(|p| {
+    pat.walk_always(|p| {
         if let hir::PatKind::Binding(_, _, ident, None) = p.kind {
             if let Some(ty::BindByValue(hir::Mutability::Not)) =
                 cx.tables.extract_binding_mode(cx.tcx.sess, p.hir_id, p.span)
@@ -303,7 +303,6 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa
                 }
             }
         }
-        true
     });
 }
 
@@ -602,7 +601,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
             by_move_spans.push(p.span);
         }
     };
-    pat.walk(|p| {
+    pat.walk_always(|p| {
         if let hir::PatKind::Binding(.., sub) = &p.kind {
             if let Some(ty::BindByValue(_)) = tables.extract_binding_mode(sess, p.hir_id, p.span) {
                 let pat_ty = tables.node_type(p.hir_id);
@@ -611,7 +610,6 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
                 }
             }
         }
-        true
     });
 
     // Found some bad by-move spans, error!
@@ -640,16 +638,16 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
         ty::BindByValue(_) => None,
         ty::BindByReference(m) => Some(m),
     };
-    pat.walk(|pat| {
+    pat.walk_always(|pat| {
         // Extract `sub` in `binding @ sub`.
         let (name, sub) = match &pat.kind {
             hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub),
-            _ => return true,
+            _ => return,
         };
 
         // Extract the mutability.
         let mut_outer = match extract_binding_mut(pat.hir_id, pat.span) {
-            None => return true,
+            None => return,
             Some(m) => m,
         };
 
@@ -698,8 +696,6 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
             }
             err.emit();
         }
-
-        true
     });
 }