From a7db1a4861e33f89181511a2e19aaa38e37e7f7a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 4 Sep 2019 02:43:49 +0200 Subject: [PATCH] or-patterns: address review comments. --- src/librustc_resolve/late.rs | 27 +++++++++++++++++++++++---- src/libsyntax/ast.rs | 5 +---- src/libsyntax/visit.rs | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 2056e7b9104..f3c70462512 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1109,7 +1109,7 @@ fn check_trait_item(&mut self, ident: Ident, ns: Namespace, span: Span, err: } fn resolve_params(&mut self, params: &[Param]) { - let mut bindings = smallvec![(false, <_>::default())]; + let mut bindings = smallvec![(false, Default::default())]; for Param { pat, ty, .. } in params { self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings); self.visit_ty(ty); @@ -1255,7 +1255,7 @@ fn resolve_arm(&mut self, arm: &Arm) { /// Arising from `source`, resolve a top level pattern. fn resolve_pattern_top(&mut self, pat: &Pat, pat_src: PatternSource) { - self.resolve_pattern(pat, pat_src, &mut smallvec![(false, <_>::default())]); + self.resolve_pattern(pat, pat_src, &mut smallvec![(false, Default::default())]); } fn resolve_pattern( @@ -1270,6 +1270,25 @@ fn resolve_pattern( visit::walk_pat(self, pat); } + /// Resolve bindings in a pattern. This is a helper to `resolve_pattern`. + /// + /// ### `bindings` + /// + /// A stack of sets of bindings accumulated. + /// + /// In each set, `false` denotes that a found binding in it should be interpreted as + /// re-binding an already bound binding. This results in an error. Meanwhile, `true` + /// denotes that a found binding in the set should result in reusing this binding + /// rather than creating a fresh one. In other words, `false` and `true` correspond + /// to product (e.g., `(a, b)`) and sum/or contexts (e.g., `p_0 | ... | p_i`) respectively. + /// + /// When called at the top level, the stack should have a single element with `false`. + /// Otherwise, pushing to the stack happens as or-patterns are encountered and the + /// context needs to be switched to `true` and then `false` for each `p_i. + /// When each `p_i` has been dealt with, the top set is merged with its parent. + /// When a whole or-pattern has been dealt with, the thing happens. + /// + /// See the implementation and `fresh_binding` for more details. fn resolve_pattern_inner( &mut self, pat: &Pat, @@ -1301,12 +1320,12 @@ fn resolve_pattern_inner( // Add a new set of bindings to the stack. `true` here records that when a // binding already exists in this set, it should not result in an error because // `V1(a) | V2(a)` must be allowed and are checked for consistency later. - bindings.push((true, <_>::default())); + bindings.push((true, Default::default())); for p in ps { // Now we need to switch back to a product context so that each // part of the or-pattern internally rejects already bound names. // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad. - bindings.push((false, <_>::default())); + bindings.push((false, Default::default())); self.resolve_pattern_inner(p, pat_src, bindings); // Move up the non-overlapping bindings to the or-pattern. // Existing bindings just get "merged". diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e0eaad0d1a7..c93e6d11ce7 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -563,7 +563,7 @@ pub(super) fn to_ty(&self) -> Option> { /// Walk top-down and call `it` in each place where a pattern occurs /// starting with the root pattern `walk` is called on. If `it` returns - /// false then we will decend no further but siblings will be processed. + /// false then we will descend no further but siblings will be processed. pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) { if !it(self) { return; @@ -1150,9 +1150,6 @@ pub enum ExprKind { Type(P, P), /// A `let pat = expr` expression that is only semantically allowed in the condition /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`). - /// - /// The `Vec>` is for or-patterns at the top level. - /// FIXME(54883): Change this to just `P`. Let(P, P), /// An `if` block, with an optional `else` block. /// diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index e64123c2382..421c327aa41 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -831,7 +831,7 @@ pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) { pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { visitor.visit_pat(&arm.pat); - // HACK(or_patterns; Centril | dlrobertson): + // NOTE(or_patterns; Centril | dlrobertson): // If you change this, also change the hack in `lowering.rs`. walk_list!(visitor, visit_expr, &arm.guard); visitor.visit_expr(&arm.body); -- 2.44.0