From 65fafd9414915fe33bc69fb4bfefa8629b5e42ea Mon Sep 17 00:00:00 2001 From: Suchith J N Date: Sat, 15 Apr 2017 10:14:09 +0530 Subject: [PATCH 1/5] [41272] - code for desugaring iflet changed --- src/librustc/hir/lowering.rs | 97 ++++---------------------------- src/test/run-pass/issue-41272.rs | 13 +++++ 2 files changed, 23 insertions(+), 87 deletions(-) create mode 100644 src/test/run-pass/issue-41272.rs diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 30fec50d4eb6f..adefd2a8d7baa 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2033,7 +2033,6 @@ impl<'a> LoweringContext<'a> { // // match { // => , - // [_ if => ,] // _ => [ | ()] // } @@ -2047,93 +2046,17 @@ impl<'a> LoweringContext<'a> { arms.push(self.arm(hir_vec![pat], body_expr)); } - // `[_ if => ,]` - // `_ => [ | ()]` + // _ => [|()] { - let mut current: Option<&Expr> = else_opt.as_ref().map(|p| &**p); - let mut else_exprs: Vec> = vec![current]; - - // First, we traverse the AST and recursively collect all - // `else` branches into else_exprs, e.g.: - // - // if let Some(_) = x { - // ... - // } else if ... { // Expr1 - // ... - // } else if ... { // Expr2 - // ... - // } else { // Expr3 - // ... - // } - // - // ... results in else_exprs = [Some(&Expr1), - // Some(&Expr2), - // Some(&Expr3)] - // - // Because there also the case there is no `else`, these - // entries can also be `None`, as in: - // - // if let Some(_) = x { - // ... - // } else if ... { // Expr1 - // ... - // } else if ... { // Expr2 - // ... - // } - // - // ... results in else_exprs = [Some(&Expr1), - // Some(&Expr2), - // None] - // - // The last entry in this list is always translated into - // the final "unguard" wildcard arm of the `match`. In the - // case of a `None`, it becomes `_ => ()`. - loop { - if let Some(e) = current { - // There is an else branch at this level - if let ExprKind::If(_, _, ref else_opt) = e.node { - // The else branch is again an if-expr - current = else_opt.as_ref().map(|p| &**p); - else_exprs.push(current); - } else { - // The last item in the list is not an if-expr, - // stop here - break - } - } else { - // We have no more else branch - break - } - } - - // Now translate the list of nested else-branches into the - // arms of the match statement. - for else_expr in else_exprs { - if let Some(else_expr) = else_expr { - let (guard, body) = if let ExprKind::If(ref cond, - ref then, - _) = else_expr.node { - let then = self.lower_block(then, false); - (Some(cond), - self.expr_block(then, ThinVec::new())) - } else { - (None, - self.lower_expr(else_expr)) - }; - - arms.push(hir::Arm { - attrs: hir_vec![], - pats: hir_vec![self.pat_wild(e.span)], - guard: guard.map(|e| P(self.lower_expr(e))), - body: P(body), - }); - } else { - // There was no else-branch, push a noop - let pat_under = self.pat_wild(e.span); - let unit = self.expr_tuple(e.span, hir_vec![]); - arms.push(self.arm(hir_vec![pat_under], unit)); - } - } + let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p); + let wildcard_pattern = self.pat_wild(e.span); + let body = + if let Some(else_expr) = wildcard_arm { + P(self.lower_expr(else_expr)) + } else { + self.expr_tuple(e.span, hir_vec![]) + }; + arms.push(self.arm(hir_vec![wildcard_pattern], body)); } let contains_else_clause = else_opt.is_some(); diff --git a/src/test/run-pass/issue-41272.rs b/src/test/run-pass/issue-41272.rs new file mode 100644 index 0000000000000..154aa5b8cbe63 --- /dev/null +++ b/src/test/run-pass/issue-41272.rs @@ -0,0 +1,13 @@ +struct Foo; + +impl Foo { + fn bar(&mut self) -> bool { true } +} + +/* This causes E0301. By fixing issue #41272 this problem should vanish */ +fn iflet_issue(foo: &mut Foo) { + if let Some(_) = Some(true) { + } else if foo.bar() {} +} + +fn main() {} From 4ac11becc2cb716d65cb3ebe5f13d3846ef78b93 Mon Sep 17 00:00:00 2001 From: Suchith J N Date: Sat, 15 Apr 2017 12:17:25 +0530 Subject: [PATCH 2/5] [41272] - Fixed to conform to rust project style --- src/librustc/hir/lowering.rs | 17 ++++++++--------- src/test/run-pass/issue-41272.rs | 10 ++++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index adefd2a8d7baa..994364ba181e7 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2048,15 +2048,14 @@ impl<'a> LoweringContext<'a> { // _ => [|()] { - let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p); - let wildcard_pattern = self.pat_wild(e.span); - let body = - if let Some(else_expr) = wildcard_arm { - P(self.lower_expr(else_expr)) - } else { - self.expr_tuple(e.span, hir_vec![]) - }; - arms.push(self.arm(hir_vec![wildcard_pattern], body)); + let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p); + let wildcard_pattern = self.pat_wild(e.span); + let body = if let Some(else_expr) = wildcard_arm { + P(self.lower_expr(else_expr)) + } else { + self.expr_tuple(e.span, hir_vec![]) + }; + arms.push(self.arm(hir_vec![wildcard_pattern], body)); } let contains_else_clause = else_opt.is_some(); diff --git a/src/test/run-pass/issue-41272.rs b/src/test/run-pass/issue-41272.rs index 154aa5b8cbe63..d0834a26ae77c 100644 --- a/src/test/run-pass/issue-41272.rs +++ b/src/test/run-pass/issue-41272.rs @@ -1,3 +1,13 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + struct Foo; impl Foo { From 65b04fa06869cecfbb8d76a8c8a2456aa1f3686e Mon Sep 17 00:00:00 2001 From: Suchith J N Date: Sat, 15 Apr 2017 17:21:53 +0530 Subject: [PATCH 3/5] Fixed aesthetics and test --- src/librustc/hir/lowering.rs | 8 ++++---- src/test/run-pass/issue-41272.rs | 10 ++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 994364ba181e7..a6d10c5ab9040 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2051,10 +2051,10 @@ impl<'a> LoweringContext<'a> { let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p); let wildcard_pattern = self.pat_wild(e.span); let body = if let Some(else_expr) = wildcard_arm { - P(self.lower_expr(else_expr)) - } else { - self.expr_tuple(e.span, hir_vec![]) - }; + P(self.lower_expr(else_expr)) + } else { + self.expr_tuple(e.span, hir_vec![]) + }; arms.push(self.arm(hir_vec![wildcard_pattern], body)); } diff --git a/src/test/run-pass/issue-41272.rs b/src/test/run-pass/issue-41272.rs index d0834a26ae77c..d6a0034690af8 100644 --- a/src/test/run-pass/issue-41272.rs +++ b/src/test/run-pass/issue-41272.rs @@ -14,10 +14,16 @@ impl Foo { fn bar(&mut self) -> bool { true } } -/* This causes E0301. By fixing issue #41272 this problem should vanish */ -fn iflet_issue(foo: &mut Foo) { +fn error(foo: &mut Foo) { if let Some(_) = Some(true) { } else if foo.bar() {} } +fn ok(foo: &mut Foo) { + if let Some(_) = Some(true) { + } else { + if foo.bar() {} + } +} + fn main() {} From 6fc7d45d64dd9489a94b2acfd4d1044482e95e2d Mon Sep 17 00:00:00 2001 From: Suchith J N Date: Sat, 15 Apr 2017 17:35:30 +0530 Subject: [PATCH 4/5] Fixed aesthetics of if let block --- src/librustc/hir/lowering.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index a6d10c5ab9040..d65603007533f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2051,10 +2051,10 @@ impl<'a> LoweringContext<'a> { let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p); let wildcard_pattern = self.pat_wild(e.span); let body = if let Some(else_expr) = wildcard_arm { - P(self.lower_expr(else_expr)) - } else { - self.expr_tuple(e.span, hir_vec![]) - }; + P(self.lower_expr(else_expr)) + } else { + self.expr_tuple(e.span, hir_vec![]) + }; arms.push(self.arm(hir_vec![wildcard_pattern], body)); } From 5649b3796fa3f8b32116f13e81b44361169ec686 Mon Sep 17 00:00:00 2001 From: Suchith J N Date: Sat, 15 Apr 2017 17:40:54 +0530 Subject: [PATCH 5/5] Aesthetic issue. Corrected indentation --- src/librustc/hir/lowering.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d65603007533f..0fd906ae5e4a3 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2051,9 +2051,9 @@ impl<'a> LoweringContext<'a> { let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p); let wildcard_pattern = self.pat_wild(e.span); let body = if let Some(else_expr) = wildcard_arm { - P(self.lower_expr(else_expr)) + P(self.lower_expr(else_expr)) } else { - self.expr_tuple(e.span, hir_vec![]) + self.expr_tuple(e.span, hir_vec![]) }; arms.push(self.arm(hir_vec![wildcard_pattern], body)); }