Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #17865 - ShoyuVanilla:exhaust-block, r=Veykril
fix: Missing non-exhaustive let diagnostics inside async or unsafe block The reason that this test doesn't have a pointer deref case is because the following code; ```rust fn test(ptr: *const Result<i32, !>) { unsafe { let Ok(_x) = *ptr; } } ``` is getting a block with no stmts but tail one in here(thus, no diagnostic error), https://github.com/rust-lang/rust-analyzer/blob/0daeb5c0b05cfdf2101b0f078c27539099bf38e6/crates/hir-ty/src/diagnostics/expr.rs#L256-L257 while the following is getting a block with a single stmt without tail 🤔 ```rust fn test(x: Result<i32, &'static !>) { let Ok(_y) = x; } ``` I'll make a more deep inspection and file this as a new issue _Originally posted by `@ShoyuVanilla` in https://github.com/rust-lang/rust-analyzer/pull/17853#discussion_r1712993585_
bors 2024-08-12
parent 18414cd · parent db24cf5 · commit 32a86cb
-rw-r--r--crates/hir-ty/src/diagnostics/expr.rs9
-rw-r--r--crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs39
2 files changed, 46 insertions, 2 deletions
diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs
index e52fae06d7..06c9b2e0e5 100644
--- a/crates/hir-ty/src/diagnostics/expr.rs
+++ b/crates/hir-ty/src/diagnostics/expr.rs
@@ -117,7 +117,7 @@ impl ExprValidator {
Expr::If { .. } => {
self.check_for_unnecessary_else(id, expr, db);
}
- Expr::Block { .. } => {
+ Expr::Block { .. } | Expr::Async { .. } | Expr::Unsafe { .. } => {
self.validate_block(db, expr);
}
_ => {}
@@ -254,7 +254,12 @@ impl ExprValidator {
}
fn validate_block(&mut self, db: &dyn HirDatabase, expr: &Expr) {
- let Expr::Block { statements, .. } = expr else { return };
+ let (Expr::Block { statements, .. }
+ | Expr::Async { statements, .. }
+ | Expr::Unsafe { statements, .. }) = expr
+ else {
+ return;
+ };
let pattern_arena = Arena::new();
let cx = MatchCheckCtx::new(self.owner.module(db.upcast()), self.owner, db);
for stmt in &**statements {
diff --git a/crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs b/crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs
index 1a4d2877ef..5a6977c255 100644
--- a/crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs
+++ b/crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs
@@ -44,4 +44,43 @@ fn main() {
"#,
);
}
+
+ #[test]
+ fn option_nonexhaustive_inside_blocks() {
+ check_diagnostics(
+ r#"
+//- minicore: option
+fn main() {
+ '_a: {
+ let None = Some(5);
+ //^^^^ error: non-exhaustive pattern: `Some(_)` not covered
+ }
+}
+"#,
+ );
+
+ check_diagnostics(
+ r#"
+//- minicore: future, option
+fn main() {
+ let _ = async {
+ let None = Some(5);
+ //^^^^ error: non-exhaustive pattern: `Some(_)` not covered
+ };
+}
+"#,
+ );
+
+ check_diagnostics(
+ r#"
+//- minicore: option
+fn main() {
+ unsafe {
+ let None = Some(5);
+ //^^^^ error: non-exhaustive pattern: `Some(_)` not covered
+ }
+}
+"#,
+ );
+ }
}