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