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