Skip to content

Commit 67bd578

Browse files
ChayimFriedman2tysg
authored andcommitted
Fix if in rust-lang#11561
1 parent 8535474 commit 67bd578

File tree

1 file changed

+61
-5
lines changed

1 file changed

+61
-5
lines changed

crates/syntax/src/ast/expr_ext.rs

+61-5
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,81 @@ impl From<ast::IfExpr> for ElseBranch {
4949

5050
impl ast::IfExpr {
5151
pub fn then_branch(&self) -> Option<ast::BlockExpr> {
52-
self.blocks().next()
52+
self.children_after_condition().next()
5353
}
5454

5555
pub fn else_branch(&self) -> Option<ElseBranch> {
56-
let res = match self.blocks().nth(1) {
56+
let res = match self.children_after_condition().nth(1) {
5757
Some(block) => ElseBranch::Block(block),
5858
None => {
59-
let elif: ast::IfExpr = support::child(self.syntax())?;
59+
let elif = self.children_after_condition().next()?;
6060
ElseBranch::IfExpr(elif)
6161
}
6262
};
6363
Some(res)
6464
}
6565

66-
pub fn blocks(&self) -> AstChildren<ast::BlockExpr> {
67-
support::children(self.syntax())
66+
fn children_after_condition<N: AstNode>(&self) -> impl Iterator<Item = N> {
67+
self.syntax().children().skip(1).filter_map(N::cast)
6868
}
6969
}
7070

71+
#[test]
72+
fn if_block_condition() {
73+
let parse = ast::SourceFile::parse(
74+
r#"
75+
fn test() {
76+
if { true } { "if" }
77+
else if { false } { "first elif" }
78+
else if true { "second elif" }
79+
else if (true) { "third elif" }
80+
else { "else" }
81+
}
82+
"#,
83+
);
84+
let if_ = parse.tree().syntax().descendants().find_map(ast::IfExpr::cast).unwrap();
85+
assert_eq!(if_.then_branch().unwrap().syntax().text(), r#"{ "if" }"#);
86+
let elif = match if_.else_branch().unwrap() {
87+
ElseBranch::IfExpr(elif) => elif,
88+
ElseBranch::Block(_) => panic!("should be `else if`"),
89+
};
90+
assert_eq!(elif.then_branch().unwrap().syntax().text(), r#"{ "first elif" }"#);
91+
let elif = match elif.else_branch().unwrap() {
92+
ElseBranch::IfExpr(elif) => elif,
93+
ElseBranch::Block(_) => panic!("should be `else if`"),
94+
};
95+
assert_eq!(elif.then_branch().unwrap().syntax().text(), r#"{ "second elif" }"#);
96+
let elif = match elif.else_branch().unwrap() {
97+
ElseBranch::IfExpr(elif) => elif,
98+
ElseBranch::Block(_) => panic!("should be `else if`"),
99+
};
100+
assert_eq!(elif.then_branch().unwrap().syntax().text(), r#"{ "third elif" }"#);
101+
let else_ = match elif.else_branch().unwrap() {
102+
ElseBranch::Block(else_) => else_,
103+
ElseBranch::IfExpr(_) => panic!("should be `else`"),
104+
};
105+
assert_eq!(else_.syntax().text(), r#"{ "else" }"#);
106+
}
107+
108+
#[test]
109+
fn if_condition_with_if_inside() {
110+
let parse = ast::SourceFile::parse(
111+
r#"
112+
fn test() {
113+
if if true { true } else { false } { "if" }
114+
else { "else" }
115+
}
116+
"#,
117+
);
118+
let if_ = parse.tree().syntax().descendants().find_map(ast::IfExpr::cast).unwrap();
119+
assert_eq!(if_.then_branch().unwrap().syntax().text(), r#"{ "if" }"#);
120+
let else_ = match if_.else_branch().unwrap() {
121+
ElseBranch::Block(else_) => else_,
122+
ElseBranch::IfExpr(_) => panic!("should be `else`"),
123+
};
124+
assert_eq!(else_.syntax().text(), r#"{ "else" }"#);
125+
}
126+
71127
impl ast::PrefixExpr {
72128
pub fn op_kind(&self) -> Option<UnaryOp> {
73129
let res = match self.op_token()?.kind() {

0 commit comments

Comments
 (0)