mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
159 lines
2.7 KiB
Rust
159 lines
2.7 KiB
Rust
use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
|
|
|
|
// Diagnostic: non-exhaustive-let
|
|
//
|
|
// This diagnostic is triggered if a `let` statement without an `else` branch has a non-exhaustive
|
|
// pattern.
|
|
pub(crate) fn non_exhaustive_let(
|
|
ctx: &DiagnosticsContext<'_>,
|
|
d: &hir::NonExhaustiveLet,
|
|
) -> Diagnostic {
|
|
Diagnostic::new_with_syntax_node_ptr(
|
|
ctx,
|
|
DiagnosticCode::RustcHardError("E0005"),
|
|
format!("non-exhaustive pattern: {}", d.uncovered_patterns),
|
|
d.pat.map(Into::into),
|
|
)
|
|
.stable()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::tests::check_diagnostics;
|
|
|
|
#[test]
|
|
fn option_nonexhaustive() {
|
|
check_diagnostics(
|
|
r#"
|
|
//- minicore: option
|
|
fn main() {
|
|
let None = Some(5);
|
|
//^^^^ error: non-exhaustive pattern: `Some(_)` not covered
|
|
}
|
|
"#,
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn option_exhaustive() {
|
|
check_diagnostics(
|
|
r#"
|
|
//- minicore: option
|
|
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
|
|
}
|
|
}
|
|
"#,
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn min_exhaustive() {
|
|
check_diagnostics(
|
|
r#"
|
|
//- minicore: result
|
|
fn test(x: Result<i32, !>) {
|
|
let Ok(_y) = x;
|
|
}
|
|
"#,
|
|
);
|
|
|
|
check_diagnostics(
|
|
r#"
|
|
//- minicore: result
|
|
fn test(x: Result<i32, &'static !>) {
|
|
let Ok(_y) = x;
|
|
//^^^^^^ error: non-exhaustive pattern: `Err(_)` not covered
|
|
}
|
|
"#,
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn empty_patterns_normalize() {
|
|
check_diagnostics(
|
|
r#"
|
|
enum Infallible {}
|
|
|
|
trait Foo {
|
|
type Assoc;
|
|
}
|
|
enum Enum<T: Foo> {
|
|
A,
|
|
B(T::Assoc),
|
|
}
|
|
|
|
impl Foo for () {
|
|
type Assoc = Infallible;
|
|
}
|
|
|
|
fn foo(v: Enum<()>) {
|
|
let Enum::A = v;
|
|
}
|
|
"#,
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn regression_20259() {
|
|
check_diagnostics(
|
|
r#"
|
|
//- minicore: deref
|
|
use core::ops::Deref;
|
|
|
|
struct Foo<T>(T);
|
|
|
|
impl<T> Deref for Foo<T> {
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
fn test(x: Foo<(i32, bool)>) {
|
|
let (_a, _b): &(i32, bool) = &x;
|
|
}
|
|
"#,
|
|
);
|
|
}
|
|
}
|