From 70a65e9d1ffa6c3e39bb0eff3c653f6329e2f16b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 15 May 2019 16:05:39 +0200 Subject: [PATCH] let_chains: Handle in resolve. --- src/librustc_resolve/lib.rs | 62 ++++++++++++++----------------------- 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0fbd0666ad1..fdef707e347 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -485,8 +485,8 @@ type BindingMap = FxHashMap; #[derive(Copy, Clone, PartialEq, Eq, Debug)] enum PatternSource { Match, - IfLet, - WhileLet, + // FIXME(54883): Consider fusing with `Let` below once let-statements support or-patterns. + LetExpr, Let, For, FnParam, @@ -496,9 +496,7 @@ impl PatternSource { fn descr(self) -> &'static str { match self { PatternSource::Match => "match binding", - PatternSource::IfLet => "if let binding", - PatternSource::WhileLet => "while let binding", - PatternSource::Let => "let binding", + PatternSource::Let | PatternSource::LetExpr => "let binding", PatternSource::For => "for binding", PatternSource::FnParam => "function parameter", } @@ -3057,13 +3055,7 @@ impl<'a> Resolver<'a> { fn resolve_arm(&mut self, arm: &Arm) { self.ribs[ValueNS].push(Rib::new(NormalRibKind)); - let mut bindings_list = FxHashMap::default(); - for pattern in &arm.pats { - self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list); - } - - // This has to happen *after* we determine which pat_idents are variants. - self.check_consistent_bindings(&arm.pats); + self.resolve_pats(&arm.pats, PatternSource::Match); if let Some(ast::Guard::If(ref expr)) = arm.guard { self.visit_expr(expr) @@ -3073,6 +3065,16 @@ impl<'a> Resolver<'a> { self.ribs[ValueNS].pop(); } + /// Arising from `source`, resolve a sequence of patterns (top level or-patterns). + fn resolve_pats(&mut self, pats: &[P], source: PatternSource) { + let mut bindings_list = FxHashMap::default(); + for pat in pats { + self.resolve_pattern(pat, source, &mut bindings_list); + } + // This has to happen *after* we determine which pat_idents are variants + self.check_consistent_bindings(pats); + } + fn resolve_block(&mut self, block: &Block) { debug!("(resolving block) entering block"); // Move down in the graph, if there's an anonymous module rooted here. @@ -3151,8 +3153,7 @@ impl<'a> Resolver<'a> { ); } Some(..) if pat_src == PatternSource::Match || - pat_src == PatternSource::IfLet || - pat_src == PatternSource::WhileLet => { + pat_src == PatternSource::LetExpr => { // `Variant1(a) | Variant2(a)`, ok // Reuse definition from the first `a`. res = self.ribs[ValueNS].last_mut().unwrap().bindings[&ident]; @@ -4345,41 +4346,26 @@ impl<'a> Resolver<'a> { visit::walk_expr(self, expr); } - ExprKind::IfLet(ref pats, ref subexpression, ref if_block, ref optional_else) => { - self.visit_expr(subexpression); + ExprKind::Let(ref pats, ref scrutinee) => { + self.visit_expr(scrutinee); + self.resolve_pats(pats, PatternSource::LetExpr); + } + ExprKind::If(ref cond, ref then, ref opt_else) => { self.ribs[ValueNS].push(Rib::new(NormalRibKind)); - let mut bindings_list = FxHashMap::default(); - for pat in pats { - self.resolve_pattern(pat, PatternSource::IfLet, &mut bindings_list); - } - // This has to happen *after* we determine which pat_idents are variants - self.check_consistent_bindings(pats); - self.visit_block(if_block); + self.visit_expr(cond); + self.visit_block(then); self.ribs[ValueNS].pop(); - optional_else.as_ref().map(|expr| self.visit_expr(expr)); + opt_else.as_ref().map(|expr| self.visit_expr(expr)); } ExprKind::Loop(ref block, label) => self.resolve_labeled_block(label, expr.id, &block), ExprKind::While(ref subexpression, ref block, label) => { self.with_resolved_label(label, expr.id, |this| { - this.visit_expr(subexpression); - this.visit_block(block); - }); - } - - ExprKind::WhileLet(ref pats, ref subexpression, ref block, label) => { - self.with_resolved_label(label, expr.id, |this| { - this.visit_expr(subexpression); this.ribs[ValueNS].push(Rib::new(NormalRibKind)); - let mut bindings_list = FxHashMap::default(); - for pat in pats { - this.resolve_pattern(pat, PatternSource::WhileLet, &mut bindings_list); - } - // This has to happen *after* we determine which pat_idents are variants. - this.check_consistent_bindings(pats); + this.visit_expr(subexpression); this.visit_block(block); this.ribs[ValueNS].pop(); });