mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 21:54:42 +00:00
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),
0daeb5c0b0/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_
This commit is contained in:
commit
32a86cb1da
2 changed files with 46 additions and 2 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue