diff options
Diffstat (limited to 'crates/hir_ty/src/tests/never_type.rs')
-rw-r--r-- | crates/hir_ty/src/tests/never_type.rs | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/crates/hir_ty/src/tests/never_type.rs b/crates/hir_ty/src/tests/never_type.rs new file mode 100644 index 000000000..49538b572 --- /dev/null +++ b/crates/hir_ty/src/tests/never_type.rs | |||
@@ -0,0 +1,409 @@ | |||
1 | use expect::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 | } | ||