Skip to content

Commit

Permalink
Auto merge of #17865 - ShoyuVanilla:exhaust-block, r=Veykril
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
bors committed Aug 12, 2024
2 parents 18414cd + db24cf5 commit 32a86cb
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
9 changes: 7 additions & 2 deletions crates/hir-ty/src/diagnostics/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
_ => {}
Expand Down Expand Up @@ -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 {
Expand Down
39 changes: 39 additions & 0 deletions crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,45 @@ fn main() {
fn main() {
let Some(_) | None = Some(5);
}
"#,
);
}

#[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
}
}
"#,
);
}
Expand Down

0 comments on commit 32a86cb

Please sign in to comment.