]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/patterns.rs
Replaced fold with for loop
[rust.git] / crates / hir_ty / src / tests / patterns.rs
1 use expect_test::expect;
2
3 use super::{check, check_infer, check_infer_with_mismatches, check_types};
4
5 #[test]
6 fn infer_pattern() {
7     check_infer(
8         r#"
9         fn test(x: &i32) {
10             let y = x;
11             let &z = x;
12             let a = z;
13             let (c, d) = (1, "hello");
14
15             for (e, f) in some_iter {
16                 let g = e;
17             }
18
19             if let [val] = opt {
20                 let h = val;
21             }
22
23             if let x @ true = &true {}
24
25             let lambda = |a: u64, b, c: i32| { a + b; c };
26
27             let ref ref_to_x = x;
28             let mut mut_x = x;
29             let ref mut mut_ref_to_x = x;
30             let k = mut_ref_to_x;
31         }
32         "#,
33         expect![[r#"
34             8..9 'x': &i32
35             17..400 '{     ...o_x; }': ()
36             27..28 'y': &i32
37             31..32 'x': &i32
38             42..44 '&z': &i32
39             43..44 'z': i32
40             47..48 'x': &i32
41             58..59 'a': i32
42             62..63 'z': i32
43             73..79 '(c, d)': (i32, &str)
44             74..75 'c': i32
45             77..78 'd': &str
46             82..94 '(1, "hello")': (i32, &str)
47             83..84 '1': i32
48             86..93 '"hello"': &str
49             101..151 'for (e...     }': ()
50             105..111 '(e, f)': ({unknown}, {unknown})
51             106..107 'e': {unknown}
52             109..110 'f': {unknown}
53             115..124 'some_iter': {unknown}
54             125..151 '{     ...     }': ()
55             139..140 'g': {unknown}
56             143..144 'e': {unknown}
57             157..204 'if let...     }': ()
58             164..169 '[val]': [{unknown}]
59             165..168 'val': {unknown}
60             172..175 'opt': [{unknown}]
61             176..204 '{     ...     }': ()
62             190..191 'h': {unknown}
63             194..197 'val': {unknown}
64             210..236 'if let...rue {}': ()
65             217..225 'x @ true': &bool
66             221..225 'true': bool
67             221..225 'true': bool
68             228..233 '&true': &bool
69             229..233 'true': bool
70             234..236 '{}': ()
71             246..252 'lambda': |u64, u64, i32| -> i32
72             255..287 '|a: u6...b; c }': |u64, u64, i32| -> i32
73             256..257 'a': u64
74             264..265 'b': u64
75             267..268 'c': i32
76             275..287 '{ a + b; c }': i32
77             277..278 'a': u64
78             277..282 'a + b': u64
79             281..282 'b': u64
80             284..285 'c': i32
81             298..310 'ref ref_to_x': &&i32
82             313..314 'x': &i32
83             324..333 'mut mut_x': &i32
84             336..337 'x': &i32
85             347..367 'ref mu...f_to_x': &mut &i32
86             370..371 'x': &i32
87             381..382 'k': &mut &i32
88             385..397 'mut_ref_to_x': &mut &i32
89         "#]],
90     );
91 }
92
93 #[test]
94 fn infer_literal_pattern() {
95     check_infer_with_mismatches(
96         r#"
97         fn any<T>() -> T { loop {} }
98         fn test(x: &i32) {
99             if let "foo" = any() {}
100             if let 1 = any() {}
101             if let 1u32 = any() {}
102             if let 1f32 = any() {}
103             if let 1.0 = any() {}
104             if let true = any() {}
105         }
106         "#,
107         expect![[r#"
108             17..28 '{ loop {} }': T
109             19..26 'loop {}': !
110             24..26 '{}': ()
111             37..38 'x': &i32
112             46..208 '{     ...) {} }': ()
113             52..75 'if let...y() {}': ()
114             59..64 '"foo"': &str
115             59..64 '"foo"': &str
116             67..70 'any': fn any<&str>() -> &str
117             67..72 'any()': &str
118             73..75 '{}': ()
119             80..99 'if let...y() {}': ()
120             87..88 '1': i32
121             87..88 '1': i32
122             91..94 'any': fn any<i32>() -> i32
123             91..96 'any()': i32
124             97..99 '{}': ()
125             104..126 'if let...y() {}': ()
126             111..115 '1u32': u32
127             111..115 '1u32': u32
128             118..121 'any': fn any<u32>() -> u32
129             118..123 'any()': u32
130             124..126 '{}': ()
131             131..153 'if let...y() {}': ()
132             138..142 '1f32': f32
133             138..142 '1f32': f32
134             145..148 'any': fn any<f32>() -> f32
135             145..150 'any()': f32
136             151..153 '{}': ()
137             158..179 'if let...y() {}': ()
138             165..168 '1.0': f64
139             165..168 '1.0': f64
140             171..174 'any': fn any<f64>() -> f64
141             171..176 'any()': f64
142             177..179 '{}': ()
143             184..206 'if let...y() {}': ()
144             191..195 'true': bool
145             191..195 'true': bool
146             198..201 'any': fn any<bool>() -> bool
147             198..203 'any()': bool
148             204..206 '{}': ()
149         "#]],
150     );
151 }
152
153 #[test]
154 fn infer_range_pattern() {
155     check_infer_with_mismatches(
156         r#"
157         fn test(x: &i32) {
158             if let 1..76 = 2u32 {}
159             if let 1..=76 = 2u32 {}
160         }
161         "#,
162         expect![[r#"
163             8..9 'x': &i32
164             17..75 '{     ...2 {} }': ()
165             23..45 'if let...u32 {}': ()
166             30..35 '1..76': u32
167             38..42 '2u32': u32
168             43..45 '{}': ()
169             50..73 'if let...u32 {}': ()
170             57..63 '1..=76': u32
171             66..70 '2u32': u32
172             71..73 '{}': ()
173         "#]],
174     );
175 }
176
177 #[test]
178 fn infer_pattern_match_ergonomics() {
179     check_infer(
180         r#"
181         struct A<T>(T);
182
183         fn test() {
184             let A(n) = &A(1);
185             let A(n) = &mut A(1);
186         }
187         "#,
188         expect![[r#"
189             27..78 '{     ...(1); }': ()
190             37..41 'A(n)': A<i32>
191             39..40 'n': &i32
192             44..49 '&A(1)': &A<i32>
193             45..46 'A': A<i32>(i32) -> A<i32>
194             45..49 'A(1)': A<i32>
195             47..48 '1': i32
196             59..63 'A(n)': A<i32>
197             61..62 'n': &mut i32
198             66..75 '&mut A(1)': &mut A<i32>
199             71..72 'A': A<i32>(i32) -> A<i32>
200             71..75 'A(1)': A<i32>
201             73..74 '1': i32
202         "#]],
203     );
204 }
205
206 #[test]
207 fn infer_pattern_match_ergonomics_ref() {
208     cov_mark::check!(match_ergonomics_ref);
209     check_infer(
210         r#"
211         fn test() {
212             let v = &(1, &2);
213             let (_, &w) = v;
214         }
215         "#,
216         expect![[r#"
217             10..56 '{     ...= v; }': ()
218             20..21 'v': &(i32, &i32)
219             24..32 '&(1, &2)': &(i32, &i32)
220             25..32 '(1, &2)': (i32, &i32)
221             26..27 '1': i32
222             29..31 '&2': &i32
223             30..31 '2': i32
224             42..49 '(_, &w)': (i32, &i32)
225             43..44 '_': i32
226             46..48 '&w': &i32
227             47..48 'w': i32
228             52..53 'v': &(i32, &i32)
229         "#]],
230     );
231 }
232
233 #[test]
234 fn infer_pattern_match_slice() {
235     check_infer(
236         r#"
237         fn test() {
238             let slice: &[f64] = &[0.0];
239             match slice {
240                 &[] => {},
241                 &[a] => {
242                     a;
243                 },
244                 &[b, c] => {
245                     b;
246                     c;
247                 }
248                 _ => {}
249             }
250         }
251         "#,
252         expect![[r#"
253             10..209 '{     ...   } }': ()
254             20..25 'slice': &[f64]
255             36..42 '&[0.0]': &[f64; 1]
256             37..42 '[0.0]': [f64; 1]
257             38..41 '0.0': f64
258             48..207 'match ...     }': ()
259             54..59 'slice': &[f64]
260             70..73 '&[]': &[f64]
261             71..73 '[]': [f64]
262             77..79 '{}': ()
263             89..93 '&[a]': &[f64]
264             90..93 '[a]': [f64]
265             91..92 'a': f64
266             97..123 '{     ...     }': ()
267             111..112 'a': f64
268             133..140 '&[b, c]': &[f64]
269             134..140 '[b, c]': [f64]
270             135..136 'b': f64
271             138..139 'c': f64
272             144..185 '{     ...     }': ()
273             158..159 'b': f64
274             173..174 'c': f64
275             194..195 '_': &[f64]
276             199..201 '{}': ()
277         "#]],
278     );
279 }
280
281 #[test]
282 fn infer_pattern_match_string_literal() {
283     check_infer_with_mismatches(
284         r#"
285         fn test() {
286             let s: &str = "hello";
287             match s {
288                 "hello" => {}
289                 _ => {}
290             }
291         }
292         "#,
293         expect![[r#"
294             10..98 '{     ...   } }': ()
295             20..21 's': &str
296             30..37 '"hello"': &str
297             43..96 'match ...     }': ()
298             49..50 's': &str
299             61..68 '"hello"': &str
300             61..68 '"hello"': &str
301             72..74 '{}': ()
302             83..84 '_': &str
303             88..90 '{}': ()
304         "#]],
305     );
306 }
307
308 #[test]
309 fn infer_pattern_match_or() {
310     check_infer_with_mismatches(
311         r#"
312         fn test() {
313             let s: &str = "hello";
314             match s {
315                 "hello" | "world" => {}
316                 _ => {}
317             }
318         }
319         "#,
320         expect![[r#"
321             10..108 '{     ...   } }': ()
322             20..21 's': &str
323             30..37 '"hello"': &str
324             43..106 'match ...     }': ()
325             49..50 's': &str
326             61..68 '"hello"': &str
327             61..68 '"hello"': &str
328             61..78 '"hello...world"': &str
329             71..78 '"world"': &str
330             71..78 '"world"': &str
331             82..84 '{}': ()
332             93..94 '_': &str
333             98..100 '{}': ()
334         "#]],
335     );
336 }
337
338 #[test]
339 fn infer_pattern_match_arr() {
340     check_infer(
341         r#"
342         fn test() {
343             let arr: [f64; 2] = [0.0, 1.0];
344             match arr {
345                 [1.0, a] => {
346                     a;
347                 },
348                 [b, c] => {
349                     b;
350                     c;
351                 }
352             }
353         }
354         "#,
355         expect![[r#"
356             10..179 '{     ...   } }': ()
357             20..23 'arr': [f64; 2]
358             36..46 '[0.0, 1.0]': [f64; 2]
359             37..40 '0.0': f64
360             42..45 '1.0': f64
361             52..177 'match ...     }': ()
362             58..61 'arr': [f64; 2]
363             72..80 '[1.0, a]': [f64; 2]
364             73..76 '1.0': f64
365             73..76 '1.0': f64
366             78..79 'a': f64
367             84..110 '{     ...     }': ()
368             98..99 'a': f64
369             120..126 '[b, c]': [f64; 2]
370             121..122 'b': f64
371             124..125 'c': f64
372             130..171 '{     ...     }': ()
373             144..145 'b': f64
374             159..160 'c': f64
375         "#]],
376     );
377 }
378
379 #[test]
380 fn infer_adt_pattern() {
381     check_infer(
382         r#"
383         enum E {
384             A { x: usize },
385             B
386         }
387
388         struct S(u32, E);
389
390         fn test() {
391             let e = E::A { x: 3 };
392
393             let S(y, z) = foo;
394             let E::A { x: new_var } = e;
395
396             match e {
397                 E::A { x } => x,
398                 E::B if foo => 1,
399                 E::B => 10,
400             };
401
402             let ref d @ E::A { .. } = e;
403             d;
404         }
405         "#,
406         expect![[r#"
407             67..288 '{     ...  d; }': ()
408             77..78 'e': E
409             81..94 'E::A { x: 3 }': E
410             91..92 '3': usize
411             105..112 'S(y, z)': S
412             107..108 'y': u32
413             110..111 'z': E
414             115..118 'foo': S
415             128..147 'E::A {..._var }': E
416             138..145 'new_var': usize
417             150..151 'e': E
418             158..244 'match ...     }': usize
419             164..165 'e': E
420             176..186 'E::A { x }': E
421             183..184 'x': usize
422             190..191 'x': usize
423             201..205 'E::B': E
424             209..212 'foo': bool
425             216..217 '1': usize
426             227..231 'E::B': E
427             235..237 '10': usize
428             255..274 'ref d ...{ .. }': &E
429             263..274 'E::A { .. }': E
430             277..278 'e': E
431             284..285 'd': &E
432         "#]],
433     );
434 }
435
436 #[test]
437 fn enum_variant_through_self_in_pattern() {
438     check_infer(
439         r#"
440         enum E {
441             A { x: usize },
442             B(usize),
443             C
444         }
445
446         impl E {
447             fn test() {
448                 match (loop {}) {
449                     Self::A { x } => { x; },
450                     Self::B(x) => { x; },
451                     Self::C => {},
452                 };
453             }
454         }
455         "#,
456         expect![[r#"
457             75..217 '{     ...     }': ()
458             85..210 'match ...     }': ()
459             92..99 'loop {}': !
460             97..99 '{}': ()
461             115..128 'Self::A { x }': E
462             125..126 'x': usize
463             132..138 '{ x; }': ()
464             134..135 'x': usize
465             152..162 'Self::B(x)': E
466             160..161 'x': usize
467             166..172 '{ x; }': ()
468             168..169 'x': usize
469             186..193 'Self::C': E
470             197..199 '{}': ()
471         "#]],
472     );
473 }
474
475 #[test]
476 fn infer_generics_in_patterns() {
477     check_infer(
478         r#"
479         struct A<T> {
480             x: T,
481         }
482
483         enum Option<T> {
484             Some(T),
485             None,
486         }
487
488         fn test(a1: A<u32>, o: Option<u64>) {
489             let A { x: x2 } = a1;
490             let A::<i64> { x: x3 } = A { x: 1 };
491             match o {
492                 Option::Some(t) => t,
493                 _ => 1,
494             };
495         }
496         "#,
497         expect![[r#"
498             78..80 'a1': A<u32>
499             90..91 'o': Option<u64>
500             106..243 '{     ...  }; }': ()
501             116..127 'A { x: x2 }': A<u32>
502             123..125 'x2': u32
503             130..132 'a1': A<u32>
504             142..160 'A::<i6...: x3 }': A<i64>
505             156..158 'x3': i64
506             163..173 'A { x: 1 }': A<i64>
507             170..171 '1': i64
508             179..240 'match ...     }': u64
509             185..186 'o': Option<u64>
510             197..212 'Option::Some(t)': Option<u64>
511             210..211 't': u64
512             216..217 't': u64
513             227..228 '_': Option<u64>
514             232..233 '1': u64
515         "#]],
516     );
517 }
518
519 #[test]
520 fn infer_const_pattern() {
521     check(
522         r#"
523 enum Option<T> { None }
524 use Option::None;
525 struct Foo;
526 const Bar: usize = 1;
527
528 fn test() {
529     let a: Option<u32> = None;
530     let b: Option<i64> = match a {
531         None => None,
532     };
533     let _: () = match () { Foo => () };
534                         // ^^^ expected (), got Foo
535     let _: () = match () { Bar => () };
536                         // ^^^ expected (), got usize
537 }
538         "#,
539     );
540 }
541
542 #[test]
543 fn infer_guard() {
544     check_infer(
545         r#"
546 struct S;
547 impl S { fn foo(&self) -> bool { false } }
548
549 fn main() {
550     match S {
551         s if s.foo() => (),
552     }
553 }
554         "#,
555         expect![[r#"
556             27..31 'self': &S
557             41..50 '{ false }': bool
558             43..48 'false': bool
559             64..115 '{     ...   } }': ()
560             70..113 'match ...     }': ()
561             76..77 'S': S
562             88..89 's': S
563             93..94 's': S
564             93..100 's.foo()': bool
565             104..106 '()': ()
566     "#]],
567     )
568 }
569
570 #[test]
571 fn match_ergonomics_in_closure_params() {
572     check_infer(
573         r#"
574 //- minicore: fn
575 fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
576
577 fn test() {
578     foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
579     foo(&(1, "a"), |(x, y)| x);
580 }
581 "#,
582         expect![[r#"
583             32..33 't': T
584             38..39 'f': F
585             49..60 '{ loop {} }': U
586             51..58 'loop {}': !
587             56..58 '{}': ()
588             72..171 '{     ... x); }': ()
589             78..81 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
590             78..105 'foo(&(...y)| x)': i32
591             82..91 '&(1, "a")': &(i32, &str)
592             83..91 '(1, "a")': (i32, &str)
593             84..85 '1': i32
594             87..90 '"a"': &str
595             93..104 '|&(x, y)| x': |&(i32, &str)| -> i32
596             94..101 '&(x, y)': &(i32, &str)
597             95..101 '(x, y)': (i32, &str)
598             96..97 'x': i32
599             99..100 'y': &str
600             103..104 'x': i32
601             142..145 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
602             142..168 'foo(&(...y)| x)': &i32
603             146..155 '&(1, "a")': &(i32, &str)
604             147..155 '(1, "a")': (i32, &str)
605             148..149 '1': i32
606             151..154 '"a"': &str
607             157..167 '|(x, y)| x': |&(i32, &str)| -> &i32
608             158..164 '(x, y)': (i32, &str)
609             159..160 'x': &i32
610             162..163 'y': &&str
611             166..167 'x': &i32
612         "#]],
613     );
614 }
615
616 #[test]
617 fn slice_tail_pattern() {
618     check_infer(
619         r#"
620         fn foo(params: &[i32]) {
621             match params {
622                 [head, tail @ ..] => {
623                 }
624             }
625         }
626         "#,
627         expect![[r#"
628             7..13 'params': &[i32]
629             23..92 '{     ...   } }': ()
630             29..90 'match ...     }': ()
631             35..41 'params': &[i32]
632             52..69 '[head,... @ ..]': [i32]
633             53..57 'head': &i32
634             59..68 'tail @ ..': &[i32]
635             66..68 '..': [i32]
636             73..84 '{         }': ()
637         "#]],
638     );
639 }
640
641 #[test]
642 fn box_pattern() {
643     check_infer(
644         r#"
645         pub struct Global;
646         #[lang = "owned_box"]
647         pub struct Box<T, A = Global>(T);
648
649         fn foo(params: Box<i32>) {
650             match params {
651                 box integer => {}
652             }
653         }
654         "#,
655         expect![[r#"
656             83..89 'params': Box<i32, Global>
657             101..155 '{     ...   } }': ()
658             107..153 'match ...     }': ()
659             113..119 'params': Box<i32, Global>
660             130..141 'box integer': Box<i32, Global>
661             134..141 'integer': i32
662             145..147 '{}': ()
663         "#]],
664     );
665     check_infer(
666         r#"
667         #[lang = "owned_box"]
668         pub struct Box<T>(T);
669
670         fn foo(params: Box<i32>) {
671             match params {
672                 box integer => {}
673             }
674         }
675         "#,
676         expect![[r#"
677             52..58 'params': Box<i32>
678             70..124 '{     ...   } }': ()
679             76..122 'match ...     }': ()
680             82..88 'params': Box<i32>
681             99..110 'box integer': Box<i32>
682             103..110 'integer': i32
683             114..116 '{}': ()
684         "#]],
685     );
686 }
687
688 #[test]
689 fn tuple_ellipsis_pattern() {
690     check_infer_with_mismatches(
691         r#"
692 fn foo(tuple: (u8, i16, f32)) {
693     match tuple {
694         (.., b, c) => {},
695         (a, .., c) => {},
696         (a, b, ..) => {},
697         (a, b) => {/*too short*/}
698         (a, b, c, d) => {/*too long*/}
699         _ => {}
700     }
701 }"#,
702         expect![[r#"
703             7..12 'tuple': (u8, i16, f32)
704             30..224 '{     ...   } }': ()
705             36..222 'match ...     }': ()
706             42..47 'tuple': (u8, i16, f32)
707             58..68 '(.., b, c)': (u8, i16, f32)
708             63..64 'b': i16
709             66..67 'c': f32
710             72..74 '{}': ()
711             84..94 '(a, .., c)': (u8, i16, f32)
712             85..86 'a': u8
713             92..93 'c': f32
714             98..100 '{}': ()
715             110..120 '(a, b, ..)': (u8, i16, f32)
716             111..112 'a': u8
717             114..115 'b': i16
718             124..126 '{}': ()
719             136..142 '(a, b)': (u8, i16)
720             137..138 'a': u8
721             140..141 'b': i16
722             146..161 '{/*too short*/}': ()
723             170..182 '(a, b, c, d)': (u8, i16, f32, {unknown})
724             171..172 'a': u8
725             174..175 'b': i16
726             177..178 'c': f32
727             180..181 'd': {unknown}
728             186..200 '{/*too long*/}': ()
729             209..210 '_': (u8, i16, f32)
730             214..216 '{}': ()
731             136..142: expected (u8, i16, f32), got (u8, i16)
732             170..182: expected (u8, i16, f32), got (u8, i16, f32, {unknown})
733         "#]],
734     );
735 }
736
737 #[test]
738 fn tuple_struct_ellipsis_pattern() {
739     check_infer(
740         r#"
741 struct Tuple(u8, i16, f32);
742 fn foo(tuple: Tuple) {
743     match tuple {
744         Tuple(.., b, c) => {},
745         Tuple(a, .., c) => {},
746         Tuple(a, b, ..) => {},
747         Tuple(a, b) => {/*too short*/}
748         Tuple(a, b, c, d) => {/*too long*/}
749         _ => {}
750     }
751 }"#,
752         expect![[r#"
753             35..40 'tuple': Tuple
754             49..268 '{     ...   } }': ()
755             55..266 'match ...     }': ()
756             61..66 'tuple': Tuple
757             77..92 'Tuple(.., b, c)': Tuple
758             87..88 'b': i16
759             90..91 'c': f32
760             96..98 '{}': ()
761             108..123 'Tuple(a, .., c)': Tuple
762             114..115 'a': u8
763             121..122 'c': f32
764             127..129 '{}': ()
765             139..154 'Tuple(a, b, ..)': Tuple
766             145..146 'a': u8
767             148..149 'b': i16
768             158..160 '{}': ()
769             170..181 'Tuple(a, b)': Tuple
770             176..177 'a': u8
771             179..180 'b': i16
772             185..200 '{/*too short*/}': ()
773             209..226 'Tuple(... c, d)': Tuple
774             215..216 'a': u8
775             218..219 'b': i16
776             221..222 'c': f32
777             224..225 'd': {unknown}
778             230..244 '{/*too long*/}': ()
779             253..254 '_': Tuple
780             258..260 '{}': ()
781         "#]],
782     );
783 }
784
785 #[test]
786 fn const_block_pattern() {
787     check_infer(
788         r#"
789 struct Foo(usize);
790 fn foo(foo: Foo) {
791     match foo {
792         const { Foo(15 + 32) } => {},
793         _ => {}
794     }
795 }"#,
796         expect![[r#"
797             26..29 'foo': Foo
798             36..115 '{     ...   } }': ()
799             42..113 'match ...     }': ()
800             48..51 'foo': Foo
801             62..84 'const ... 32) }': Foo
802             68..84 '{ Foo(... 32) }': Foo
803             70..73 'Foo': Foo(usize) -> Foo
804             70..82 'Foo(15 + 32)': Foo
805             74..76 '15': usize
806             74..81 '15 + 32': usize
807             79..81 '32': usize
808             88..90 '{}': ()
809             100..101 '_': Foo
810             105..107 '{}': ()
811         "#]],
812     );
813 }
814
815 #[test]
816 fn macro_pat() {
817     check_types(
818         r#"
819 macro_rules! pat {
820     ($name:ident) => { Enum::Variant1($name) }
821 }
822
823 enum Enum {
824     Variant1(u8),
825     Variant2,
826 }
827
828 fn f(e: Enum) {
829     match e {
830         pat!(bind) => {
831             bind;
832           //^^^^ u8
833         }
834         Enum::Variant2 => {}
835     }
836 }
837     "#,
838     )
839 }
840
841 #[test]
842 fn type_mismatch_in_or_pattern() {
843     check_infer_with_mismatches(
844         r#"
845 fn main() {
846     match (false,) {
847         (true | (),) => {}
848         (() | true,) => {}
849         (_ | (),) => {}
850         (() | _,) => {}
851     }
852 }
853 "#,
854         expect![[r#"
855             10..142 '{     ...   } }': ()
856             16..140 'match ...     }': ()
857             22..30 '(false,)': (bool,)
858             23..28 'false': bool
859             41..53 '(true | (),)': (bool,)
860             42..46 'true': bool
861             42..46 'true': bool
862             42..51 'true | ()': bool
863             49..51 '()': ()
864             57..59 '{}': ()
865             68..80 '(() | true,)': ((),)
866             69..71 '()': ()
867             69..78 '() | true': ()
868             74..78 'true': bool
869             74..78 'true': bool
870             84..86 '{}': ()
871             95..104 '(_ | (),)': (bool,)
872             96..97 '_': bool
873             96..102 '_ | ()': bool
874             100..102 '()': ()
875             108..110 '{}': ()
876             119..128 '(() | _,)': ((),)
877             120..122 '()': ()
878             120..126 '() | _': ()
879             125..126 '_': bool
880             132..134 '{}': ()
881             49..51: expected bool, got ()
882             68..80: expected (bool,), got ((),)
883             69..71: expected bool, got ()
884             69..78: expected bool, got ()
885             100..102: expected bool, got ()
886             119..128: expected (bool,), got ((),)
887             120..122: expected bool, got ()
888             120..126: expected bool, got ()
889         "#]],
890     );
891 }
892
893 #[test]
894 fn pattern_lookup_in_value_ns() {
895     check_types(
896         r#"
897 use self::Constructor::*;
898 struct IntRange {
899     range: (),
900 }
901 enum Constructor {
902     IntRange(IntRange),
903 }
904 fn main() {
905     match Constructor::IntRange(IntRange { range: () }) {
906         IntRange(x) => {
907             x;
908           //^ IntRange
909         }
910         Constructor::IntRange(x) => {
911             x;
912           //^ IntRange
913         }
914     }
915 }
916     "#,
917     );
918 }
919
920 #[test]
921 fn if_let_guards() {
922     check_types(
923         r#"
924 fn main() {
925     match (0,) {
926         opt if let (x,) = opt => {
927             x;
928           //^ i32
929         }
930         _ => {}
931     }
932 }
933     "#,
934     );
935 }