]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/never_type.rs
Merge #11842
[rust.git] / crates / hir_ty / src / tests / never_type.rs
1 use expect_test::expect;
2
3 use super::{check_infer_with_mismatches, check_types};
4
5 #[test]
6 fn infer_never1() {
7     check_types(
8         r#"
9 fn test() {
10     let t = return;
11     t;
12 } //^ !
13 "#,
14     );
15 }
16
17 #[test]
18 fn infer_never2() {
19     check_types(
20         r#"
21 fn gen<T>() -> T { loop {} }
22
23 fn test() {
24     let a = gen();
25     if false { a } else { loop {} };
26     a;
27 } //^ !
28 "#,
29     );
30 }
31
32 #[test]
33 fn infer_never3() {
34     check_types(
35         r#"
36 fn gen<T>() -> T { loop {} }
37
38 fn test() {
39     let a = gen();
40     if false { loop {} } else { a };
41     a;
42   //^ !
43 }
44 "#,
45     );
46 }
47
48 #[test]
49 fn never_type_in_generic_args() {
50     check_types(
51         r#"
52 enum Option<T> { None, Some(T) }
53
54 fn test() {
55     let a = if true { Option::None } else { Option::Some(return) };
56     a;
57 } //^ Option<!>
58 "#,
59     );
60 }
61
62 #[test]
63 fn never_type_can_be_reinferred1() {
64     check_types(
65         r#"
66 fn gen<T>() -> T { loop {} }
67
68 fn test() {
69     let a = gen();
70     if false { loop {} } else { a };
71     a;
72   //^ ()
73     if false { a };
74 }
75 "#,
76     );
77 }
78
79 #[test]
80 fn never_type_can_be_reinferred2() {
81     check_types(
82         r#"
83 enum Option<T> { None, Some(T) }
84
85 fn test() {
86     let a = if true { Option::None } else { Option::Some(return) };
87     a;
88   //^ Option<i32>
89     match 42 {
90         42 => a,
91         _ => Option::Some(42),
92     };
93 }
94 "#,
95     );
96 }
97
98 #[test]
99 fn never_type_can_be_reinferred3() {
100     check_types(
101         r#"
102 enum Option<T> { None, Some(T) }
103
104 fn test() {
105     let a = if true { Option::None } else { Option::Some(return) };
106     a;
107   //^ Option<&str>
108     match 42 {
109         42 => a,
110         _ => Option::Some("str"),
111     };
112 }
113 "#,
114     );
115 }
116
117 #[test]
118 fn match_no_arm() {
119     check_types(
120         r#"
121 enum Void {}
122
123 fn test(a: Void) {
124     let t = match a {};
125     t;
126 } //^ !
127 "#,
128     );
129 }
130
131 #[test]
132 fn match_unknown_arm() {
133     check_types(
134         r#"
135 fn test(a: Option) {
136     let t = match 0 {
137         _ => unknown,
138     };
139     t;
140 } //^ {unknown}
141 "#,
142     );
143 }
144
145 #[test]
146 fn if_never() {
147     check_types(
148         r#"
149 fn test() {
150     let i = if true {
151         loop {}
152     } else {
153         3.0
154     };
155     i;
156 } //^ f64
157 "#,
158     );
159 }
160
161 #[test]
162 fn if_else_never() {
163     check_types(
164         r#"
165 fn test(input: bool) {
166     let i = if input {
167         2.0
168     } else {
169         return
170     };
171     i;
172 } //^ f64
173 "#,
174     );
175 }
176
177 #[test]
178 fn match_first_arm_never() {
179     check_types(
180         r#"
181 fn test(a: i32) {
182     let i = match a {
183         1 => return,
184         2 => 2.0,
185         3 => loop {},
186         _ => 3.0,
187     };
188     i;
189 } //^ f64
190 "#,
191     );
192 }
193
194 #[test]
195 fn match_second_arm_never() {
196     check_types(
197         r#"
198 fn test(a: i32) {
199     let i = match a {
200         1 => 3.0,
201         2 => loop {},
202         3 => 3.0,
203         _ => return,
204     };
205     i;
206 } //^ f64
207 "#,
208     );
209 }
210
211 #[test]
212 fn match_all_arms_never() {
213     check_types(
214         r#"
215 fn test(a: i32) {
216     let i = match a {
217         2 => return,
218         _ => loop {},
219     };
220     i;
221 } //^ !
222 "#,
223     );
224 }
225
226 #[test]
227 fn match_no_never_arms() {
228     check_types(
229         r#"
230 fn test(a: i32) {
231     let i = match a {
232         2 => 2.0,
233         _ => 3.0,
234     };
235     i;
236 } //^ f64
237 "#,
238     );
239 }
240
241 #[test]
242 fn diverging_expression_1() {
243     check_infer_with_mismatches(
244         r"
245         //- /main.rs
246         fn test1() {
247             let x: u32 = return;
248         }
249         fn test2() {
250             let x: u32 = { return; };
251         }
252         fn test3() {
253             let x: u32 = loop {};
254         }
255         fn test4() {
256             let x: u32 = { loop {} };
257         }
258         fn test5() {
259             let x: u32 = { if true { loop {}; } else { loop {}; } };
260         }
261         fn test6() {
262             let x: u32 = { let y: u32 = { loop {}; }; };
263         }
264         ",
265         expect![[r"
266             11..39 '{     ...urn; }': ()
267             21..22 'x': u32
268             30..36 'return': !
269             51..84 '{     ...; }; }': ()
270             61..62 'x': u32
271             70..81 '{ return; }': u32
272             72..78 'return': !
273             96..125 '{     ... {}; }': ()
274             106..107 'x': u32
275             115..122 'loop {}': !
276             120..122 '{}': ()
277             137..170 '{     ...} }; }': ()
278             147..148 'x': u32
279             156..167 '{ loop {} }': u32
280             158..165 'loop {}': !
281             163..165 '{}': ()
282             182..246 '{     ...} }; }': ()
283             192..193 'x': u32
284             201..243 '{ if t...}; } }': u32
285             203..241 'if tru... {}; }': u32
286             206..210 'true': bool
287             211..223 '{ loop {}; }': u32
288             213..220 'loop {}': !
289             218..220 '{}': ()
290             229..241 '{ loop {}; }': u32
291             231..238 'loop {}': !
292             236..238 '{}': ()
293             258..310 '{     ...; }; }': ()
294             268..269 'x': u32
295             277..307 '{ let ...; }; }': u32
296             283..284 'y': u32
297             292..304 '{ loop {}; }': u32
298             294..301 'loop {}': !
299             299..301 '{}': ()
300         "]],
301     );
302 }
303
304 #[test]
305 fn diverging_expression_2() {
306     check_infer_with_mismatches(
307         r#"
308         //- /main.rs
309         fn test1() {
310             // should give type mismatch
311             let x: u32 = { loop {}; "foo" };
312         }
313         "#,
314         expect![[r#"
315             11..84 '{     ..." }; }': ()
316             54..55 'x': u32
317             63..81 '{ loop...foo" }': u32
318             65..72 'loop {}': !
319             70..72 '{}': ()
320             74..79 '"foo"': &str
321             74..79: expected u32, got &str
322         "#]],
323     );
324 }
325
326 #[test]
327 fn diverging_expression_3_break() {
328     check_infer_with_mismatches(
329         r"
330         //- /main.rs
331         fn test1() {
332             // should give type mismatch
333             let x: u32 = { loop { break; } };
334         }
335         fn test2() {
336             // should give type mismatch
337             let x: u32 = { for a in b { break; }; };
338             // should give type mismatch as well
339             let x: u32 = { for a in b {}; };
340             // should give type mismatch as well
341             let x: u32 = { for a in b { return; }; };
342         }
343         fn test3() {
344             // should give type mismatch
345             let x: u32 = { while true { break; }; };
346             // should give type mismatch as well -- there's an implicit break, even if it's never hit
347             let x: u32 = { while true {}; };
348             // should give type mismatch as well
349             let x: u32 = { while true { return; }; };
350         }
351         ",
352         expect![[r#"
353             11..85 '{     ...} }; }': ()
354             54..55 'x': u32
355             63..82 '{ loop...k; } }': u32
356             65..80 'loop { break; }': ()
357             70..80 '{ break; }': ()
358             72..77 'break': !
359             65..80: expected u32, got ()
360             97..343 '{     ...; }; }': ()
361             140..141 'x': u32
362             149..175 '{ for ...; }; }': u32
363             151..172 'for a ...eak; }': ()
364             155..156 'a': {unknown}
365             160..161 'b': {unknown}
366             162..172 '{ break; }': ()
367             164..169 'break': !
368             226..227 'x': u32
369             235..253 '{ for ... {}; }': u32
370             237..250 'for a in b {}': ()
371             241..242 'a': {unknown}
372             246..247 'b': {unknown}
373             248..250 '{}': ()
374             304..305 'x': u32
375             313..340 '{ for ...; }; }': u32
376             315..337 'for a ...urn; }': ()
377             319..320 'a': {unknown}
378             324..325 'b': {unknown}
379             326..337 '{ return; }': ()
380             328..334 'return': !
381             149..175: expected u32, got ()
382             235..253: expected u32, got ()
383             313..340: expected u32, got ()
384             355..654 '{     ...; }; }': ()
385             398..399 'x': u32
386             407..433 '{ whil...; }; }': u32
387             409..430 'while ...eak; }': ()
388             415..419 'true': bool
389             420..430 '{ break; }': ()
390             422..427 'break': !
391             537..538 'x': u32
392             546..564 '{ whil... {}; }': u32
393             548..561 'while true {}': ()
394             554..558 'true': bool
395             559..561 '{}': ()
396             615..616 'x': u32
397             624..651 '{ whil...; }; }': u32
398             626..648 'while ...urn; }': ()
399             632..636 'true': bool
400             637..648 '{ return; }': ()
401             639..645 'return': !
402             407..433: expected u32, got ()
403             546..564: expected u32, got ()
404             624..651: expected u32, got ()
405         "#]],
406     );
407 }
408
409 #[test]
410 fn let_else_must_diverge() {
411     check_infer_with_mismatches(
412         r#"
413         fn f() {
414             let 1 = 2 else {
415                 return;
416             };
417         }
418         "#,
419         expect![[r#"
420             7..54 '{     ...  }; }': ()
421             17..18 '1': i32
422             17..18 '1': i32
423             21..22 '2': i32
424             28..51 '{     ...     }': !
425             38..44 'return': !
426         "#]],
427     );
428     check_infer_with_mismatches(
429         r#"
430         fn f() {
431             let 1 = 2 else {};
432         }
433         "#,
434         expect![[r#"
435             7..33 '{     ... {}; }': ()
436             17..18 '1': i32
437             17..18 '1': i32
438             21..22 '2': i32
439             28..30 '{}': !
440             28..30: expected !, got ()
441         "#]],
442     );
443 }