mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 14:13:58 +00:00
fix: Fix lowering of for loops dropping the loop
block
This commit is contained in:
parent
b10dd83c2e
commit
fbca403ebe
6 changed files with 65 additions and 9 deletions
|
@ -737,7 +737,7 @@ impl ExprCollector<'_> {
|
||||||
/// `try { <stmts>; }` into `'<new_label>: { <stmts>; ::std::ops::Try::from_output(()) }`
|
/// `try { <stmts>; }` into `'<new_label>: { <stmts>; ::std::ops::Try::from_output(()) }`
|
||||||
/// and save the `<new_label>` to use it as a break target for desugaring of the `?` operator.
|
/// and save the `<new_label>` to use it as a break target for desugaring of the `?` operator.
|
||||||
fn desugar_try_block(&mut self, e: BlockExpr) -> ExprId {
|
fn desugar_try_block(&mut self, e: BlockExpr) -> ExprId {
|
||||||
let Some(try_from_output) = LangItem::TryTraitFromOutput.path(self.db, self.krate) else {
|
let Some(try_from_output) = self.lang_path(LangItem::TryTraitFromOutput) else {
|
||||||
return self.collect_block(e);
|
return self.collect_block(e);
|
||||||
};
|
};
|
||||||
let label = self
|
let label = self
|
||||||
|
@ -840,10 +840,10 @@ impl ExprCollector<'_> {
|
||||||
fn collect_for_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::ForExpr) -> ExprId {
|
fn collect_for_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::ForExpr) -> ExprId {
|
||||||
let Some((into_iter_fn, iter_next_fn, option_some, option_none)) = (|| {
|
let Some((into_iter_fn, iter_next_fn, option_some, option_none)) = (|| {
|
||||||
Some((
|
Some((
|
||||||
LangItem::IntoIterIntoIter.path(self.db, self.krate)?,
|
self.lang_path(LangItem::IntoIterIntoIter)?,
|
||||||
LangItem::IteratorNext.path(self.db, self.krate)?,
|
self.lang_path(LangItem::IteratorNext)?,
|
||||||
LangItem::OptionSome.path(self.db, self.krate)?,
|
self.lang_path(LangItem::OptionSome)?,
|
||||||
LangItem::OptionNone.path(self.db, self.krate)?,
|
self.lang_path(LangItem::OptionNone)?,
|
||||||
))
|
))
|
||||||
})() else {
|
})() else {
|
||||||
// Some of the needed lang items are missing, so we can't desugar
|
// Some of the needed lang items are missing, so we can't desugar
|
||||||
|
@ -896,6 +896,15 @@ 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,
|
syntax_ptr,
|
||||||
);
|
);
|
||||||
|
let loop_inner = self.alloc_expr(
|
||||||
|
Expr::Block {
|
||||||
|
id: None,
|
||||||
|
statements: Box::default(),
|
||||||
|
tail: Some(loop_inner),
|
||||||
|
label: None,
|
||||||
|
},
|
||||||
|
syntax_ptr,
|
||||||
|
);
|
||||||
let loop_outer = self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr);
|
let loop_outer = self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr);
|
||||||
let iter_binding = self.alloc_binding(iter_name, BindingAnnotation::Mutable);
|
let iter_binding = self.alloc_binding(iter_name, BindingAnnotation::Mutable);
|
||||||
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 });
|
||||||
|
@ -923,10 +932,10 @@ impl ExprCollector<'_> {
|
||||||
fn collect_try_operator(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::TryExpr) -> ExprId {
|
fn collect_try_operator(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::TryExpr) -> ExprId {
|
||||||
let Some((try_branch, cf_continue, cf_break, try_from_residual)) = (|| {
|
let Some((try_branch, cf_continue, cf_break, try_from_residual)) = (|| {
|
||||||
Some((
|
Some((
|
||||||
LangItem::TryTraitBranch.path(self.db, self.krate)?,
|
self.lang_path(LangItem::TryTraitBranch)?,
|
||||||
LangItem::ControlFlowContinue.path(self.db, self.krate)?,
|
self.lang_path(LangItem::ControlFlowContinue)?,
|
||||||
LangItem::ControlFlowBreak.path(self.db, self.krate)?,
|
self.lang_path(LangItem::ControlFlowBreak)?,
|
||||||
LangItem::TryTraitFromResidual.path(self.db, self.krate)?,
|
self.lang_path(LangItem::TryTraitFromResidual)?,
|
||||||
))
|
))
|
||||||
})() else {
|
})() else {
|
||||||
// Some of the needed lang items are missing, so we can't desugar
|
// Some of the needed lang items are missing, so we can't desugar
|
||||||
|
@ -2053,6 +2062,10 @@ impl ExprCollector<'_> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// endregion: format
|
// endregion: format
|
||||||
|
|
||||||
|
fn lang_path(&self, lang: LangItem) -> Option<Path> {
|
||||||
|
lang.path(self.db, self.krate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pat_literal_to_hir(lit: &ast::LiteralPat) -> Option<(Literal, ast::Literal)> {
|
fn pat_literal_to_hir(lit: &ast::LiteralPat) -> Option<(Literal, ast::Literal)> {
|
||||||
|
|
|
@ -142,6 +142,41 @@ mod m {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn desugar_for_loop() {
|
||||||
|
let (db, body, def) = lower(
|
||||||
|
r#"
|
||||||
|
//- minicore: iterator
|
||||||
|
fn main() {
|
||||||
|
for ident in 0..10 {
|
||||||
|
foo();
|
||||||
|
bar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect![[r#"
|
||||||
|
fn main() -> () {
|
||||||
|
match builtin#lang(into_iter)(
|
||||||
|
(0) ..(10) ,
|
||||||
|
) {
|
||||||
|
mut <ra@gennew>11 => loop {
|
||||||
|
match builtin#lang(next)(
|
||||||
|
&mut <ra@gennew>11,
|
||||||
|
) {
|
||||||
|
builtin#lang(None) => break,
|
||||||
|
builtin#lang(Some)(ident) => {
|
||||||
|
foo();
|
||||||
|
bar()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}"#]]
|
||||||
|
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn desugar_builtin_format_args() {
|
fn desugar_builtin_format_args() {
|
||||||
let (db, body, def) = lower(
|
let (db, body, def) = lower(
|
||||||
|
|
|
@ -206,6 +206,7 @@ fn expr_macro_def_expanded_in_various_places() {
|
||||||
100..119 'for _ ...!() {}': ()
|
100..119 'for _ ...!() {}': ()
|
||||||
100..119 'for _ ...!() {}': ()
|
100..119 'for _ ...!() {}': ()
|
||||||
100..119 'for _ ...!() {}': ()
|
100..119 'for _ ...!() {}': ()
|
||||||
|
100..119 'for _ ...!() {}': ()
|
||||||
104..105 '_': IntoIterator::Item<isize>
|
104..105 '_': IntoIterator::Item<isize>
|
||||||
117..119 '{}': ()
|
117..119 '{}': ()
|
||||||
124..134 '|| spam!()': impl Fn() -> isize
|
124..134 '|| spam!()': impl Fn() -> isize
|
||||||
|
@ -299,6 +300,7 @@ fn expr_macro_rules_expanded_in_various_places() {
|
||||||
114..133 'for _ ...!() {}': ()
|
114..133 'for _ ...!() {}': ()
|
||||||
114..133 'for _ ...!() {}': ()
|
114..133 'for _ ...!() {}': ()
|
||||||
114..133 'for _ ...!() {}': ()
|
114..133 'for _ ...!() {}': ()
|
||||||
|
114..133 'for _ ...!() {}': ()
|
||||||
118..119 '_': IntoIterator::Item<isize>
|
118..119 '_': IntoIterator::Item<isize>
|
||||||
131..133 '{}': ()
|
131..133 '{}': ()
|
||||||
138..148 '|| spam!()': impl Fn() -> isize
|
138..148 '|| spam!()': impl Fn() -> isize
|
||||||
|
|
|
@ -371,6 +371,7 @@ fn diverging_expression_3_break() {
|
||||||
151..172 'for a ...eak; }': ()
|
151..172 'for a ...eak; }': ()
|
||||||
151..172 'for a ...eak; }': ()
|
151..172 'for a ...eak; }': ()
|
||||||
151..172 'for a ...eak; }': ()
|
151..172 'for a ...eak; }': ()
|
||||||
|
151..172 'for a ...eak; }': ()
|
||||||
155..156 'a': {unknown}
|
155..156 'a': {unknown}
|
||||||
160..161 'b': {unknown}
|
160..161 'b': {unknown}
|
||||||
162..172 '{ break; }': ()
|
162..172 '{ break; }': ()
|
||||||
|
@ -387,6 +388,7 @@ fn diverging_expression_3_break() {
|
||||||
237..250 'for a in b {}': ()
|
237..250 'for a in b {}': ()
|
||||||
237..250 'for a in b {}': ()
|
237..250 'for a in b {}': ()
|
||||||
237..250 'for a in b {}': ()
|
237..250 'for a in b {}': ()
|
||||||
|
237..250 'for a in b {}': ()
|
||||||
241..242 'a': {unknown}
|
241..242 'a': {unknown}
|
||||||
246..247 'b': {unknown}
|
246..247 'b': {unknown}
|
||||||
248..250 '{}': ()
|
248..250 '{}': ()
|
||||||
|
@ -402,6 +404,7 @@ fn diverging_expression_3_break() {
|
||||||
315..337 'for a ...urn; }': ()
|
315..337 'for a ...urn; }': ()
|
||||||
315..337 'for a ...urn; }': ()
|
315..337 'for a ...urn; }': ()
|
||||||
315..337 'for a ...urn; }': ()
|
315..337 'for a ...urn; }': ()
|
||||||
|
315..337 'for a ...urn; }': ()
|
||||||
319..320 'a': {unknown}
|
319..320 'a': {unknown}
|
||||||
324..325 'b': {unknown}
|
324..325 'b': {unknown}
|
||||||
326..337 '{ return; }': ()
|
326..337 '{ return; }': ()
|
||||||
|
|
|
@ -57,6 +57,7 @@ fn infer_pattern() {
|
||||||
101..151 'for (e... }': ()
|
101..151 'for (e... }': ()
|
||||||
101..151 'for (e... }': ()
|
101..151 'for (e... }': ()
|
||||||
101..151 'for (e... }': ()
|
101..151 'for (e... }': ()
|
||||||
|
101..151 'for (e... }': ()
|
||||||
105..111 '(e, f)': ({unknown}, {unknown})
|
105..111 '(e, f)': ({unknown}, {unknown})
|
||||||
106..107 'e': {unknown}
|
106..107 'e': {unknown}
|
||||||
109..110 'f': {unknown}
|
109..110 'f': {unknown}
|
||||||
|
|
|
@ -275,6 +275,7 @@ fn infer_std_crash_5() {
|
||||||
32..320 'for co... }': ()
|
32..320 'for co... }': ()
|
||||||
32..320 'for co... }': ()
|
32..320 'for co... }': ()
|
||||||
32..320 'for co... }': ()
|
32..320 'for co... }': ()
|
||||||
|
32..320 'for co... }': ()
|
||||||
36..43 'content': {unknown}
|
36..43 'content': {unknown}
|
||||||
47..60 'doesnt_matter': {unknown}
|
47..60 'doesnt_matter': {unknown}
|
||||||
61..320 '{ ... }': ()
|
61..320 '{ ... }': ()
|
||||||
|
@ -1244,6 +1245,7 @@ fn test() {
|
||||||
16..66 'for _ ... }': ()
|
16..66 'for _ ... }': ()
|
||||||
16..66 'for _ ... }': ()
|
16..66 'for _ ... }': ()
|
||||||
16..66 'for _ ... }': ()
|
16..66 'for _ ... }': ()
|
||||||
|
16..66 'for _ ... }': ()
|
||||||
20..21 '_': IntoIterator::Item<()>
|
20..21 '_': IntoIterator::Item<()>
|
||||||
25..39 '{ let x = 0; }': ()
|
25..39 '{ let x = 0; }': ()
|
||||||
31..32 'x': i32
|
31..32 'x': i32
|
||||||
|
|
Loading…
Reference in a new issue