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

Commit 4458e7f

Browse files
committed
Auto merge of rust-lang#14942 - HKalbasi:for-loop-label, r=HKalbasi
fix bug in labeled for loop desugaring fix rust-lang/rust-analyzer#14892 (comment)
2 parents 117f9b7 + f4c52b4 commit 4458e7f

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
@@ -753,10 +753,13 @@ impl ExprCollector<'_> {
753753
args: Box::new([self.collect_pat_top(e.pat())]),
754754
ellipsis: None,
755755
};
756+
let label = e.label().map(|label| self.collect_label(label));
756757
let some_arm = MatchArm {
757758
pat: self.alloc_pat_desugared(some_pat),
758759
guard: None,
759-
expr: self.collect_expr_opt(e.loop_body().map(|x| x.into())),
760+
expr: self.with_opt_labeled_rib(label, |this| {
761+
this.collect_expr_opt(e.loop_body().map(|x| x.into()))
762+
}),
760763
};
761764
let iter_name = Name::generate_new_name();
762765
let iter_binding = self.alloc_binding(iter_name.clone(), BindingAnnotation::Mutable);
@@ -778,7 +781,6 @@ impl ExprCollector<'_> {
778781
Expr::Match { expr: iter_next_expr, arms: Box::new([none_arm, some_arm]) },
779782
syntax_ptr.clone(),
780783
);
781-
let label = e.label().map(|label| self.collect_label(label));
782784
let loop_outer =
783785
self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr.clone());
784786
let iter_pat = self.alloc_pat_desugared(Pat::Bind { id: iter_binding, subpat: None });
@@ -1449,6 +1451,17 @@ impl ExprCollector<'_> {
14491451
self.label_ribs.pop();
14501452
res
14511453
}
1454+
1455+
fn with_opt_labeled_rib<T>(
1456+
&mut self,
1457+
label: Option<LabelId>,
1458+
f: impl FnOnce(&mut Self) -> T,
1459+
) -> T {
1460+
match label {
1461+
None => f(self),
1462+
Some(label) => self.with_labeled_rib(label, f),
1463+
}
1464+
}
14521465
// endregion: labels
14531466
}
14541467

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)