Skip to content

Commit 32a86cb

Browse files
committed
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 #17853 (comment)
2 parents 18414cd + db24cf5 commit 32a86cb

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

crates/hir-ty/src/diagnostics/expr.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl ExprValidator {
117117
Expr::If { .. } => {
118118
self.check_for_unnecessary_else(id, expr, db);
119119
}
120-
Expr::Block { .. } => {
120+
Expr::Block { .. } | Expr::Async { .. } | Expr::Unsafe { .. } => {
121121
self.validate_block(db, expr);
122122
}
123123
_ => {}
@@ -254,7 +254,12 @@ impl ExprValidator {
254254
}
255255

256256
fn validate_block(&mut self, db: &dyn HirDatabase, expr: &Expr) {
257-
let Expr::Block { statements, .. } = expr else { return };
257+
let (Expr::Block { statements, .. }
258+
| Expr::Async { statements, .. }
259+
| Expr::Unsafe { statements, .. }) = expr
260+
else {
261+
return;
262+
};
258263
let pattern_arena = Arena::new();
259264
let cx = MatchCheckCtx::new(self.owner.module(db.upcast()), self.owner, db);
260265
for stmt in &**statements {

crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,45 @@ fn main() {
4141
fn main() {
4242
let Some(_) | None = Some(5);
4343
}
44+
"#,
45+
);
46+
}
47+
48+
#[test]
49+
fn option_nonexhaustive_inside_blocks() {
50+
check_diagnostics(
51+
r#"
52+
//- minicore: option
53+
fn main() {
54+
'_a: {
55+
let None = Some(5);
56+
//^^^^ error: non-exhaustive pattern: `Some(_)` not covered
57+
}
58+
}
59+
"#,
60+
);
61+
62+
check_diagnostics(
63+
r#"
64+
//- minicore: future, option
65+
fn main() {
66+
let _ = async {
67+
let None = Some(5);
68+
//^^^^ error: non-exhaustive pattern: `Some(_)` not covered
69+
};
70+
}
71+
"#,
72+
);
73+
74+
check_diagnostics(
75+
r#"
76+
//- minicore: option
77+
fn main() {
78+
unsafe {
79+
let None = Some(5);
80+
//^^^^ error: non-exhaustive pattern: `Some(_)` not covered
81+
}
82+
}
4483
"#,
4584
);
4685
}

0 commit comments

Comments
 (0)