]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/patterns.rs
Add lowering of array lengths in types
[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             262..285: expected (), got usize
550         "#]],
551     );
552 }
553
554 #[test]
555 fn infer_guard() {
556     check_infer(
557         r#"
558 struct S;
559 impl S { fn foo(&self) -> bool { false } }
560
561 fn main() {
562     match S {
563         s if s.foo() => (),
564     }
565 }
566         "#,
567         expect![[r#"
568             27..31 'self': &S
569             41..50 '{ false }': bool
570             43..48 'false': bool
571             64..115 '{     ...   } }': ()
572             70..113 'match ...     }': ()
573             76..77 'S': S
574             88..89 's': S
575             93..94 's': S
576             93..100 's.foo()': bool
577             104..106 '()': ()
578     "#]],
579     )
580 }
581
582 #[test]
583 fn match_ergonomics_in_closure_params() {
584     check_infer(
585         r#"
586         #[lang = "fn_once"]
587         trait FnOnce<Args> {
588             type Output;
589         }
590
591         fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
592
593         fn test() {
594             foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
595             foo(&(1, "a"), |(x, y)| x);
596         }
597         "#,
598         expect![[r#"
599             93..94 't': T
600             99..100 'f': F
601             110..121 '{ loop {} }': U
602             112..119 'loop {}': !
603             117..119 '{}': ()
604             133..232 '{     ... x); }': ()
605             139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
606             139..166 'foo(&(...y)| x)': i32
607             143..152 '&(1, "a")': &(i32, &str)
608             144..152 '(1, "a")': (i32, &str)
609             145..146 '1': i32
610             148..151 '"a"': &str
611             154..165 '|&(x, y)| x': |&(i32, &str)| -> i32
612             155..162 '&(x, y)': &(i32, &str)
613             156..162 '(x, y)': (i32, &str)
614             157..158 'x': i32
615             160..161 'y': &str
616             164..165 'x': i32
617             203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
618             203..229 'foo(&(...y)| x)': &i32
619             207..216 '&(1, "a")': &(i32, &str)
620             208..216 '(1, "a")': (i32, &str)
621             209..210 '1': i32
622             212..215 '"a"': &str
623             218..228 '|(x, y)| x': |&(i32, &str)| -> &i32
624             219..225 '(x, y)': (i32, &str)
625             220..221 'x': &i32
626             223..224 'y': &&str
627             227..228 'x': &i32
628         "#]],
629     );
630 }
631
632 #[test]
633 fn slice_tail_pattern() {
634     check_infer(
635         r#"
636         fn foo(params: &[i32]) {
637             match params {
638                 [head, tail @ ..] => {
639                 }
640             }
641         }
642         "#,
643         expect![[r#"
644             7..13 'params': &[i32]
645             23..92 '{     ...   } }': ()
646             29..90 'match ...     }': ()
647             35..41 'params': &[i32]
648             52..69 '[head,... @ ..]': [i32]
649             53..57 'head': &i32
650             59..68 'tail @ ..': &[i32]
651             66..68 '..': [i32]
652             73..84 '{         }': ()
653         "#]],
654     );
655 }
656
657 #[test]
658 fn box_pattern() {
659     check_infer(
660         r#"
661         pub struct Global;
662         #[lang = "owned_box"]
663         pub struct Box<T, A = Global>(T);
664
665         fn foo(params: Box<i32>) {
666             match params {
667                 box integer => {}
668             }
669         }
670         "#,
671         expect![[r#"
672             83..89 'params': Box<i32, Global>
673             101..155 '{     ...   } }': ()
674             107..153 'match ...     }': ()
675             113..119 'params': Box<i32, Global>
676             130..141 'box integer': Box<i32, Global>
677             134..141 'integer': i32
678             145..147 '{}': ()
679         "#]],
680     );
681     check_infer(
682         r#"
683         #[lang = "owned_box"]
684         pub struct Box<T>(T);
685
686         fn foo(params: Box<i32>) {
687             match params {
688                 box integer => {}
689             }
690         }
691         "#,
692         expect![[r#"
693             52..58 'params': Box<i32>
694             70..124 '{     ...   } }': ()
695             76..122 'match ...     }': ()
696             82..88 'params': Box<i32>
697             99..110 'box integer': Box<i32>
698             103..110 'integer': i32
699             114..116 '{}': ()
700         "#]],
701     );
702 }
703
704 #[test]
705 fn tuple_ellipsis_pattern() {
706     check_infer(
707         r#"
708 fn foo(tuple: (u8, i16, f32)) {
709     match tuple {
710         (.., b, c) => {},
711         (a, .., c) => {},
712         (a, b, ..) => {},
713         (a, b) => {/*too short*/}
714         (a, b, c, d) => {/*too long*/}
715         _ => {}
716     }
717 }"#,
718         expect![[r#"
719             7..12 'tuple': (u8, i16, f32)
720             30..224 '{     ...   } }': ()
721             36..222 'match ...     }': ()
722             42..47 'tuple': (u8, i16, f32)
723             58..68 '(.., b, c)': (u8, i16, f32)
724             63..64 'b': i16
725             66..67 'c': f32
726             72..74 '{}': ()
727             84..94 '(a, .., c)': (u8, i16, f32)
728             85..86 'a': u8
729             92..93 'c': f32
730             98..100 '{}': ()
731             110..120 '(a, b, ..)': (u8, i16, f32)
732             111..112 'a': u8
733             114..115 'b': i16
734             124..126 '{}': ()
735             136..142 '(a, b)': (u8, i16, f32)
736             137..138 'a': u8
737             140..141 'b': i16
738             146..161 '{/*too short*/}': ()
739             170..182 '(a, b, c, d)': (u8, i16, f32, {unknown})
740             171..172 'a': u8
741             174..175 'b': i16
742             177..178 'c': f32
743             180..181 'd': {unknown}
744             186..200 '{/*too long*/}': ()
745             209..210 '_': (u8, i16, f32)
746             214..216 '{}': ()
747         "#]],
748     );
749 }
750
751 #[test]
752 fn tuple_struct_ellipsis_pattern() {
753     check_infer(
754         r#"
755 struct Tuple(u8, i16, f32);
756 fn foo(tuple: Tuple) {
757     match tuple {
758         Tuple(.., b, c) => {},
759         Tuple(a, .., c) => {},
760         Tuple(a, b, ..) => {},
761         Tuple(a, b) => {/*too short*/}
762         Tuple(a, b, c, d) => {/*too long*/}
763         _ => {}
764     }
765 }"#,
766         expect![[r#"
767             35..40 'tuple': Tuple
768             49..268 '{     ...   } }': ()
769             55..266 'match ...     }': ()
770             61..66 'tuple': Tuple
771             77..92 'Tuple(.., b, c)': Tuple
772             87..88 'b': i16
773             90..91 'c': f32
774             96..98 '{}': ()
775             108..123 'Tuple(a, .., c)': Tuple
776             114..115 'a': u8
777             121..122 'c': f32
778             127..129 '{}': ()
779             139..154 'Tuple(a, b, ..)': Tuple
780             145..146 'a': u8
781             148..149 'b': i16
782             158..160 '{}': ()
783             170..181 'Tuple(a, b)': Tuple
784             176..177 'a': u8
785             179..180 'b': i16
786             185..200 '{/*too short*/}': ()
787             209..226 'Tuple(... c, d)': Tuple
788             215..216 'a': u8
789             218..219 'b': i16
790             221..222 'c': f32
791             224..225 'd': {unknown}
792             230..244 '{/*too long*/}': ()
793             253..254 '_': Tuple
794             258..260 '{}': ()
795         "#]],
796     );
797 }
798
799 #[test]
800 fn const_block_pattern() {
801     check_infer(
802         r#"
803 struct Foo(usize);
804 fn foo(foo: Foo) {
805     match foo {
806         const { Foo(15 + 32) } => {},
807         _ => {}
808     }
809 }"#,
810         expect![[r#"
811             26..29 'foo': Foo
812             36..115 '{     ...   } }': ()
813             42..113 'match ...     }': ()
814             48..51 'foo': Foo
815             62..84 'const ... 32) }': Foo
816             68..84 '{ Foo(... 32) }': Foo
817             70..73 'Foo': Foo(usize) -> Foo
818             70..82 'Foo(15 + 32)': Foo
819             74..76 '15': usize
820             74..81 '15 + 32': usize
821             79..81 '32': usize
822             88..90 '{}': ()
823             100..101 '_': Foo
824             105..107 '{}': ()
825         "#]],
826     );
827 }
828
829 #[test]
830 fn macro_pat() {
831     check_types(
832         r#"
833 macro_rules! pat {
834     ($name:ident) => { Enum::Variant1($name) }
835 }
836
837 enum Enum {
838     Variant1(u8),
839     Variant2,
840 }
841
842 fn f(e: Enum) {
843     match e {
844         pat!(bind) => {
845             bind;
846           //^^^^ u8
847         }
848         Enum::Variant2 => {}
849     }
850 }
851     "#,
852     )
853 }