Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit f4c52b4

Browse files
committed
fix bug in labeled for loop desugaring
1 parent bafa6c4 commit f4c52b4

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

crates/hir-def/src/body/lower.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,10 +744,13 @@ impl ExprCollector<'_> {
744744
args: Box::new([self.collect_pat_top(e.pat())]),
745745
ellipsis: None,
746746
};
747+
let label = e.label().map(|label| self.collect_label(label));
747748
let some_arm = MatchArm {
748749
pat: self.alloc_pat_desugared(some_pat),
749750
guard: None,
750-
expr: self.collect_expr_opt(e.loop_body().map(|x| x.into())),
751+
expr: self.with_opt_labeled_rib(label, |this| {
752+
this.collect_expr_opt(e.loop_body().map(|x| x.into()))
753+
}),
751754
};
752755
let iter_name = Name::generate_new_name();
753756
let iter_binding = self.alloc_binding(iter_name.clone(), BindingAnnotation::Mutable);
@@ -769,7 +772,6 @@ impl ExprCollector<'_> {
769772
Expr::Match { expr: iter_next_expr, arms: Box::new([none_arm, some_arm]) },
770773
syntax_ptr.clone(),
771774
);
772-
let label = e.label().map(|label| self.collect_label(label));
773775
let loop_outer =
774776
self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr.clone());
775777
let iter_pat = self.alloc_pat_desugared(Pat::Bind { id: iter_binding, subpat: None });
@@ -1426,6 +1428,17 @@ impl ExprCollector<'_> {
14261428
self.label_ribs.pop();
14271429
res
14281430
}
1431+
1432+
fn with_opt_labeled_rib<T>(
1433+
&mut self,
1434+
label: Option<LabelId>,
1435+
f: impl FnOnce(&mut Self) -> T,
1436+
) -> T {
1437+
match label {
1438+
None => f(self),
1439+
Some(label) => self.with_labeled_rib(label, f),
1440+
}
1441+
}
14291442
// endregion: labels
14301443
}
14311444

crates/ide-diagnostics/src/handlers/undeclared_label.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,31 @@ fn foo() {
3333
);
3434
}
3535

36+
#[test]
37+
fn for_loop() {
38+
check_diagnostics(
39+
r#"
40+
//- minicore: iterator
41+
fn foo() {
42+
'xxx: for _ in unknown {
43+
'yyy: for _ in unknown {
44+
break 'xxx;
45+
continue 'yyy;
46+
break 'zzz;
47+
//^^^^ error: use of undeclared label `'zzz`
48+
}
49+
continue 'xxx;
50+
continue 'yyy;
51+
//^^^^ error: use of undeclared label `'yyy`
52+
break 'xxx;
53+
break 'yyy;
54+
//^^^^ error: use of undeclared label `'yyy`
55+
}
56+
}
57+
"#,
58+
);
59+
}
60+
3661
#[test]
3762
fn try_operator_desugar_works() {
3863
check_diagnostics(

0 commit comments

Comments
 (0)