fix: diagnostics for 'while let' loop with label in condition

This commit is contained in:
xffxff 2023-08-26 10:41:19 +08:00
parent 0a0bb777b1
commit 204bc2cb60
2 changed files with 40 additions and 1 deletions

View file

@ -744,7 +744,27 @@ impl ExprCollector<'_> {
fn collect_while_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::WhileExpr) -> ExprId { fn collect_while_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::WhileExpr) -> ExprId {
let label = e.label().map(|label| self.collect_label(label)); let label = e.label().map(|label| self.collect_label(label));
let body = self.collect_labelled_block_opt(label, e.loop_body()); let body = self.collect_labelled_block_opt(label, e.loop_body());
let condition = self.collect_expr_opt(e.condition());
// Labels can also be used in the condition expression, like this:
// ```
// fn main() {
// let mut optional = Some(0);
// 'my_label: while let Some(a) = match optional {
// None => break 'my_label,
// Some(val) => Some(val),
// } {
// println!("{}", a);
// optional = None;
// }
// }
// ```
let condition = match label {
Some(label) => {
self.with_labeled_rib(label, |this| this.collect_expr_opt(e.condition()))
}
None => self.collect_expr_opt(e.condition()),
};
let break_expr = let break_expr =
self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr.clone()); self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr.clone());
let if_expr = self.alloc_expr( let if_expr = self.alloc_expr(

View file

@ -34,6 +34,25 @@ fn foo() {
); );
} }
#[test]
fn while_let_loop_with_label_in_condition() {
check_diagnostics(
r#"
fn foo() {
let mut optional = Some(0);
'my_label: while let Some(a) = match optional {
None => break 'my_label,
Some(val) => Some(val),
} {
optional = None;
continue 'my_label;
}
}
"#,
);
}
#[test] #[test]
fn for_loop() { fn for_loop() {
check_diagnostics( check_diagnostics(