ide_diagnostics/handlers/
non_exhaustive_let.rs1use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
2
3pub(crate) fn non_exhaustive_let(
8 ctx: &DiagnosticsContext<'_>,
9 d: &hir::NonExhaustiveLet,
10) -> Diagnostic {
11 Diagnostic::new_with_syntax_node_ptr(
12 ctx,
13 DiagnosticCode::RustcHardError("E0005"),
14 format!("non-exhaustive pattern: {}", d.uncovered_patterns),
15 d.pat.map(Into::into),
16 )
17 .stable()
18}
19
20#[cfg(test)]
21mod tests {
22 use crate::tests::check_diagnostics;
23
24 #[test]
25 fn option_nonexhaustive() {
26 check_diagnostics(
27 r#"
28//- minicore: option
29fn main() {
30 let None = Some(5);
31 //^^^^ error: non-exhaustive pattern: `Some(_)` not covered
32}
33"#,
34 );
35 }
36
37 #[test]
38 fn option_exhaustive() {
39 check_diagnostics(
40 r#"
41//- minicore: option
42fn main() {
43 let Some(_) | None = Some(5);
44}
45"#,
46 );
47 }
48
49 #[test]
50 fn option_nonexhaustive_inside_blocks() {
51 check_diagnostics(
52 r#"
53//- minicore: option
54fn main() {
55 '_a: {
56 let None = Some(5);
57 //^^^^ error: non-exhaustive pattern: `Some(_)` not covered
58 }
59}
60"#,
61 );
62
63 check_diagnostics(
64 r#"
65//- minicore: future, option
66fn main() {
67 let _ = async {
68 let None = Some(5);
69 //^^^^ error: non-exhaustive pattern: `Some(_)` not covered
70 };
71}
72"#,
73 );
74
75 check_diagnostics(
76 r#"
77//- minicore: option
78fn main() {
79 unsafe {
80 let None = Some(5);
81 //^^^^ error: non-exhaustive pattern: `Some(_)` not covered
82 }
83}
84"#,
85 );
86 }
87
88 #[test]
89 fn min_exhaustive() {
90 check_diagnostics(
91 r#"
92//- minicore: result
93fn test(x: Result<i32, !>) {
94 let Ok(_y) = x;
95}
96"#,
97 );
98
99 check_diagnostics(
100 r#"
101//- minicore: result
102fn test(x: Result<i32, &'static !>) {
103 let Ok(_y) = x;
104 //^^^^^^ error: non-exhaustive pattern: `Err(_)` not covered
105}
106"#,
107 );
108 }
109
110 #[test]
111 fn empty_patterns_normalize() {
112 check_diagnostics(
113 r#"
114enum Infallible {}
115
116trait Foo {
117 type Assoc;
118}
119enum Enum<T: Foo> {
120 A,
121 B(T::Assoc),
122}
123
124impl Foo for () {
125 type Assoc = Infallible;
126}
127
128fn foo(v: Enum<()>) {
129 let Enum::A = v;
130}
131 "#,
132 );
133 }
134
135 #[test]
136 fn regression_20259() {
137 check_diagnostics(
138 r#"
139//- minicore: deref
140use core::ops::Deref;
141
142struct Foo<T>(T);
143
144impl<T> Deref for Foo<T> {
145 type Target = T;
146
147 fn deref(&self) -> &Self::Target {
148 &self.0
149 }
150}
151
152fn test(x: Foo<(i32, bool)>) {
153 let (_a, _b): &(i32, bool) = &x;
154}
155"#,
156 );
157 }
158
159 #[test]
160 fn uninhabited_variants() {
161 check_diagnostics(
162 r#"
163//- minicore: result
164enum Infallible {}
165
166trait Foo {
167 type Bar;
168}
169
170struct Wrapper<T> {
171 error: T,
172}
173
174struct FooWrapper<T: Foo> {
175 error: T::Bar,
176}
177
178fn foo<T: Foo<Bar = Infallible>>(result: Result<T, T::Bar>) -> T {
179 let Ok(ok) = result;
180 ok
181}
182
183fn bar<T: Foo<Bar = Infallible>>(result: Result<T, (T::Bar,)>) -> T {
184 let Ok(ok) = result;
185 ok
186}
187
188fn baz<T: Foo<Bar = Infallible>>(result: Result<T, Wrapper<T::Bar>>) -> T {
189 let Ok(ok) = result;
190 ok
191}
192
193fn qux<T: Foo<Bar = Infallible>>(result: Result<T, FooWrapper<T>>) -> T {
194 let Ok(ok) = result;
195 ok
196}
197
198fn quux<T: Foo<Bar = Infallible>>(result: Result<T, [T::Bar; 1]>) -> T {
199 let Ok(ok) = result;
200 ok
201}
202
203fn corge<T: Foo<Bar = Infallible>>(result: Result<T, (i32, T::Bar)>) -> T {
204 let Ok(ok) = result;
205 ok
206}
207"#,
208 );
209 }
210}