mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
fix bug in labeled for loop desugaring
This commit is contained in:
parent
bafa6c4ee5
commit
f4c52b40bd
2 changed files with 40 additions and 2 deletions
|
@ -744,10 +744,13 @@ impl ExprCollector<'_> {
|
||||||
args: Box::new([self.collect_pat_top(e.pat())]),
|
args: Box::new([self.collect_pat_top(e.pat())]),
|
||||||
ellipsis: None,
|
ellipsis: None,
|
||||||
};
|
};
|
||||||
|
let label = e.label().map(|label| self.collect_label(label));
|
||||||
let some_arm = MatchArm {
|
let some_arm = MatchArm {
|
||||||
pat: self.alloc_pat_desugared(some_pat),
|
pat: self.alloc_pat_desugared(some_pat),
|
||||||
guard: None,
|
guard: None,
|
||||||
expr: self.collect_expr_opt(e.loop_body().map(|x| x.into())),
|
expr: self.with_opt_labeled_rib(label, |this| {
|
||||||
|
this.collect_expr_opt(e.loop_body().map(|x| x.into()))
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
let iter_name = Name::generate_new_name();
|
let iter_name = Name::generate_new_name();
|
||||||
let iter_binding = self.alloc_binding(iter_name.clone(), BindingAnnotation::Mutable);
|
let iter_binding = self.alloc_binding(iter_name.clone(), BindingAnnotation::Mutable);
|
||||||
|
@ -769,7 +772,6 @@ impl ExprCollector<'_> {
|
||||||
Expr::Match { expr: iter_next_expr, arms: Box::new([none_arm, some_arm]) },
|
Expr::Match { expr: iter_next_expr, arms: Box::new([none_arm, some_arm]) },
|
||||||
syntax_ptr.clone(),
|
syntax_ptr.clone(),
|
||||||
);
|
);
|
||||||
let label = e.label().map(|label| self.collect_label(label));
|
|
||||||
let loop_outer =
|
let loop_outer =
|
||||||
self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr.clone());
|
self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr.clone());
|
||||||
let iter_pat = self.alloc_pat_desugared(Pat::Bind { id: iter_binding, subpat: None });
|
let iter_pat = self.alloc_pat_desugared(Pat::Bind { id: iter_binding, subpat: None });
|
||||||
|
@ -1426,6 +1428,17 @@ impl ExprCollector<'_> {
|
||||||
self.label_ribs.pop();
|
self.label_ribs.pop();
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn with_opt_labeled_rib<T>(
|
||||||
|
&mut self,
|
||||||
|
label: Option<LabelId>,
|
||||||
|
f: impl FnOnce(&mut Self) -> T,
|
||||||
|
) -> T {
|
||||||
|
match label {
|
||||||
|
None => f(self),
|
||||||
|
Some(label) => self.with_labeled_rib(label, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
// endregion: labels
|
// endregion: labels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,31 @@ fn foo() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn for_loop() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
//- minicore: iterator
|
||||||
|
fn foo() {
|
||||||
|
'xxx: for _ in unknown {
|
||||||
|
'yyy: for _ in unknown {
|
||||||
|
break 'xxx;
|
||||||
|
continue 'yyy;
|
||||||
|
break 'zzz;
|
||||||
|
//^^^^ error: use of undeclared label `'zzz`
|
||||||
|
}
|
||||||
|
continue 'xxx;
|
||||||
|
continue 'yyy;
|
||||||
|
//^^^^ error: use of undeclared label `'yyy`
|
||||||
|
break 'xxx;
|
||||||
|
break 'yyy;
|
||||||
|
//^^^^ error: use of undeclared label `'yyy`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_operator_desugar_works() {
|
fn try_operator_desugar_works() {
|
||||||
check_diagnostics(
|
check_diagnostics(
|
||||||
|
|
Loading…
Reference in a new issue