Unnamed repository; edit this file 'description' to name the repository.
Fix blocks not considering stmt without semi as tails
Lukas Wirth 2022-07-01
parent 58d5c69 · commit e5e5a09
-rw-r--r--crates/hir-def/src/body/lower.rs18
-rw-r--r--crates/hir-ty/src/tests/macros.rs27
-rw-r--r--crates/hir-ty/src/tests/regression.rs6
3 files changed, 46 insertions, 5 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index e188d80eb8..049afa8227 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -690,12 +690,26 @@ impl ExprCollector<'_> {
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 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 = 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 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,
);
diff --git a/crates/hir-ty/src/tests/macros.rs b/crates/hir-ty/src/tests/macros.rs
index 81268f37fd..a4299d9f05 100644
--- a/crates/hir-ty/src/tests/macros.rs
+++ b/crates/hir-ty/src/tests/macros.rs
@@ -1,6 +1,8 @@
use expect_test::expect;
use test_utils::{bench, bench_fixture, skip_slow_tests};
+use crate::tests::check_infer_with_mismatches;
+
use super::{check_infer, check_types};
#[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
+ "#]],
+ );
+}
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index d41470d29f..ee0a631a1b 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -1013,17 +1013,17 @@ fn cfg_tail() {
"#,
expect![[r#"
14..53 '{ ...)] 9 }': ()
- 20..31 '{ "first" }': &str
+ 20..31 '{ "first" }': ()
22..29 '"first"': &str
72..190 '{ ...] 13 }': ()
78..88 '{ "fake" }': &str
80..86 '"fake"': &str
93..103 '{ "fake" }': &str
95..101 '"fake"': &str
- 108..120 '{ "second" }': &str
+ 108..120 '{ "second" }': ()
110..118 '"second"': &str
210..273 '{ ... 15; }': ()
- 216..227 '{ "third" }': &str
+ 216..227 '{ "third" }': ()
218..225 '"third"': &str
293..357 '{ ...] 15 }': ()
299..311 '{ "fourth" }': &str