Fix blocks not considering stmt without semi as tails

This commit is contained in:
Lukas Wirth 2022-07-01 15:52:52 +02:00
parent 58d5c69a63
commit e5e5a0932d
3 changed files with 46 additions and 5 deletions

View file

@ -690,12 +690,26 @@ impl ExprCollector<'_> {
let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); let prev_def_map = mem::replace(&mut self.expander.def_map, def_map);
let prev_local_module = mem::replace(&mut self.expander.module, module); let prev_local_module = mem::replace(&mut self.expander.module, module);
let statements = block.statements().filter_map(|s| self.collect_stmt(s)).collect(); let mut statements: Vec<_> =
block.statements().filter_map(|s| self.collect_stmt(s)).collect();
let tail = block.tail_expr().and_then(|e| self.maybe_collect_expr(e)); let tail = block.tail_expr().and_then(|e| self.maybe_collect_expr(e));
let tail = tail.or_else(|| {
let stmt = statements.pop()?;
if let Statement::Expr { expr, has_semi: false } = stmt {
return Some(expr);
}
statements.push(stmt);
None
});
let syntax_node_ptr = AstPtr::new(&block.into()); let syntax_node_ptr = AstPtr::new(&block.into());
let expr_id = self.alloc_expr( let expr_id = self.alloc_expr(
Expr::Block { id: block_id, statements, tail, label: None }, Expr::Block {
id: block_id,
statements: statements.into_boxed_slice(),
tail,
label: None,
},
syntax_node_ptr, syntax_node_ptr,
); );

View file

@ -1,6 +1,8 @@
use expect_test::expect; use expect_test::expect;
use test_utils::{bench, bench_fixture, skip_slow_tests}; use test_utils::{bench, bench_fixture, skip_slow_tests};
use crate::tests::check_infer_with_mismatches;
use super::{check_infer, check_types}; use super::{check_infer, check_types};
#[test] #[test]
@ -1247,3 +1249,28 @@ fn infinitely_recursive_macro_type() {
"#]], "#]],
); );
} }
#[test]
fn cfg_tails() {
check_infer_with_mismatches(
r#"
//- /lib.rs crate:foo cfg:feature=foo
struct S {}
impl S {
fn new2(bar: u32) -> Self {
#[cfg(feature = "foo")]
{ Self { } }
#[cfg(not(feature = "foo"))]
{ Self { } }
}
}
"#,
expect![[r#"
34..37 'bar': u32
52..170 '{ ... }': S
62..106 '#[cfg(... { } }': S
96..104 'Self { }': S
"#]],
);
}

View file

@ -1013,17 +1013,17 @@ fn cfg_tail() {
"#, "#,
expect![[r#" expect![[r#"
14..53 '{ ...)] 9 }': () 14..53 '{ ...)] 9 }': ()
20..31 '{ "first" }': &str 20..31 '{ "first" }': ()
22..29 '"first"': &str 22..29 '"first"': &str
72..190 '{ ...] 13 }': () 72..190 '{ ...] 13 }': ()
78..88 '{ "fake" }': &str 78..88 '{ "fake" }': &str
80..86 '"fake"': &str 80..86 '"fake"': &str
93..103 '{ "fake" }': &str 93..103 '{ "fake" }': &str
95..101 '"fake"': &str 95..101 '"fake"': &str
108..120 '{ "second" }': &str 108..120 '{ "second" }': ()
110..118 '"second"': &str 110..118 '"second"': &str
210..273 '{ ... 15; }': () 210..273 '{ ... 15; }': ()
216..227 '{ "third" }': &str 216..227 '{ "third" }': ()
218..225 '"third"': &str 218..225 '"third"': &str
293..357 '{ ...] 15 }': () 293..357 '{ ...] 15 }': ()
299..311 '{ "fourth" }': &str 299..311 '{ "fourth" }': &str