]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/never_type.rs
Merge #9007
[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" }': &str
318             65..72 'loop {}': !
319             70..72 '{}': ()
320             74..79 '"foo"': &str
321             63..81: expected u32, got &str
322             74..79: expected u32, got &str
323         "#]],
324     );
325 }
326
327 #[test]
328 fn diverging_expression_3_break() {
329     check_infer_with_mismatches(
330         r"
331         //- /main.rs
332         fn test1() {
333             // should give type mismatch
334             let x: u32 = { loop { break; } };
335         }
336         fn test2() {
337             // should give type mismatch
338             let x: u32 = { for a in b { break; }; };
339             // should give type mismatch as well
340             let x: u32 = { for a in b {}; };
341             // should give type mismatch as well
342             let x: u32 = { for a in b { return; }; };
343         }
344         fn test3() {
345             // should give type mismatch
346             let x: u32 = { while true { break; }; };
347             // should give type mismatch as well -- there's an implicit break, even if it's never hit
348             let x: u32 = { while true {}; };
349             // should give type mismatch as well
350             let x: u32 = { while true { return; }; };
351         }
352         ",
353         expect![[r"
354             11..85 '{     ...} }; }': ()
355             54..55 'x': u32
356             63..82 '{ loop...k; } }': ()
357             65..80 'loop { break; }': ()
358             70..80 '{ break; }': ()
359             72..77 'break': !
360             63..82: expected u32, got ()
361             65..80: expected u32, got ()
362             97..343 '{     ...; }; }': ()
363             140..141 'x': u32
364             149..175 '{ for ...; }; }': ()
365             151..172 'for a ...eak; }': ()
366             155..156 'a': {unknown}
367             160..161 'b': {unknown}
368             162..172 '{ break; }': ()
369             164..169 'break': !
370             226..227 'x': u32
371             235..253 '{ for ... {}; }': ()
372             237..250 'for a in b {}': ()
373             241..242 'a': {unknown}
374             246..247 'b': {unknown}
375             248..250 '{}': ()
376             304..305 'x': u32
377             313..340 '{ for ...; }; }': ()
378             315..337 'for a ...urn; }': ()
379             319..320 'a': {unknown}
380             324..325 'b': {unknown}
381             326..337 '{ return; }': ()
382             328..334 'return': !
383             149..175: expected u32, got ()
384             235..253: expected u32, got ()
385             313..340: expected u32, got ()
386             355..654 '{     ...; }; }': ()
387             398..399 'x': u32
388             407..433 '{ whil...; }; }': ()
389             409..430 'while ...eak; }': ()
390             415..419 'true': bool
391             420..430 '{ break; }': ()
392             422..427 'break': !
393             537..538 'x': u32
394             546..564 '{ whil... {}; }': ()
395             548..561 'while true {}': ()
396             554..558 'true': bool
397             559..561 '{}': ()
398             615..616 'x': u32
399             624..651 '{ whil...; }; }': ()
400             626..648 'while ...urn; }': ()
401             632..636 'true': bool
402             637..648 '{ return; }': ()
403             639..645 'return': !
404             407..433: expected u32, got ()
405             546..564: expected u32, got ()
406             624..651: expected u32, got ()
407         "]],
408     );
409 }