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_
| -rw-r--r-- | crates/hir-ty/src/diagnostics/expr.rs | 9 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs | 39 |
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 + } +} +"#, + ); + } } |