1 use expect_test::expect;
3 use super::{check, check_infer, check_infer_with_mismatches, check_types};
13 let (c, d) = (1, "hello");
15 for (e, f) in some_iter {
23 if let x @ true = &true {}
25 let lambda = |a: u64, b, c: i32| { a + b; c };
29 let ref mut mut_ref_to_x = x;
35 17..400 '{ ...o_x; }': ()
43 73..79 '(c, d)': (i32, &str)
46 82..94 '(1, "hello")': (i32, &str)
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
68 228..233 '&true': &bool
71 246..252 'lambda': |u64, u64, i32| -> i32
72 255..287 '|a: u6...b; c }': |u64, u64, i32| -> i32
76 275..287 '{ a + b; c }': i32
81 298..310 'ref ref_to_x': &&i32
83 324..333 'mut mut_x': &i32
85 347..367 'ref mu...f_to_x': &mut &i32
87 381..382 'k': &mut &i32
88 385..397 'mut_ref_to_x': &mut &i32
94 fn infer_literal_pattern() {
95 check_infer_with_mismatches(
97 fn any<T>() -> T { loop {} }
99 if let "foo" = any() {}
101 if let 1u32 = any() {}
102 if let 1f32 = any() {}
103 if let 1.0 = any() {}
104 if let true = any() {}
108 17..28 '{ loop {} }': T
112 46..208 '{ ...) {} }': ()
113 52..75 'if let...y() {}': ()
116 67..70 'any': fn any<&str>() -> &str
119 80..99 'if let...y() {}': ()
122 91..94 'any': fn any<i32>() -> i32
125 104..126 'if let...y() {}': ()
128 118..121 'any': fn any<u32>() -> u32
129 118..123 'any()': u32
131 131..153 'if let...y() {}': ()
134 145..148 'any': fn any<f32>() -> f32
135 145..150 'any()': f32
137 158..179 'if let...y() {}': ()
140 171..174 'any': fn any<f64>() -> f64
141 171..176 'any()': f64
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
154 fn infer_range_pattern() {
155 check_infer_with_mismatches(
158 if let 1..76 = 2u32 {}
159 if let 1..=76 = 2u32 {}
164 17..75 '{ ...2 {} }': ()
165 23..45 'if let...u32 {}': ()
169 50..73 'if let...u32 {}': ()
178 fn infer_pattern_match_ergonomics() {
185 let A(n) = &mut A(1);
189 27..78 '{ ...(1); }': ()
190 37..41 'A(n)': A<i32>
192 44..49 '&A(1)': &A<i32>
193 45..46 'A': A<i32>(i32) -> A<i32>
194 45..49 'A(1)': A<i32>
196 59..63 'A(n)': A<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>
207 fn infer_pattern_match_ergonomics_ref() {
208 cov_mark::check!(match_ergonomics_ref);
217 10..56 '{ ...= v; }': ()
218 20..21 'v': &(i32, &i32)
219 24..32 '&(1, &2)': &(i32, &i32)
220 25..32 '(1, &2)': (i32, &i32)
224 42..49 '(_, &w)': (i32, &i32)
228 52..53 'v': &(i32, &i32)
234 fn infer_pattern_match_slice() {
238 let slice: &[f64] = &[0.0];
253 10..209 '{ ... } }': ()
254 20..25 'slice': &[f64]
255 36..42 '&[0.0]': &[f64; 1]
256 37..42 '[0.0]': [f64; 1]
258 48..207 'match ... }': ()
259 54..59 'slice': &[f64]
263 89..93 '&[a]': &[f64]
266 97..123 '{ ... }': ()
268 133..140 '&[b, c]': &[f64]
269 134..140 '[b, c]': [f64]
272 144..185 '{ ... }': ()
282 fn infer_pattern_match_string_literal() {
283 check_infer_with_mismatches(
286 let s: &str = "hello";
294 10..98 '{ ... } }': ()
296 30..37 '"hello"': &str
297 43..96 'match ... }': ()
299 61..68 '"hello"': &str
300 61..68 '"hello"': &str
309 fn infer_pattern_match_or() {
310 check_infer_with_mismatches(
313 let s: &str = "hello";
315 "hello" | "world" => {}
321 10..108 '{ ... } }': ()
323 30..37 '"hello"': &str
324 43..106 'match ... }': ()
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
339 fn infer_pattern_match_arr() {
343 let arr: [f64; 2] = [0.0, 1.0];
356 10..179 '{ ... } }': ()
357 20..23 'arr': [f64; 2]
358 36..46 '[0.0, 1.0]': [f64; 2]
361 52..177 'match ... }': ()
362 58..61 'arr': [f64; 2]
363 72..80 '[1.0, a]': [f64; 2]
367 84..110 '{ ... }': ()
369 120..126 '[b, c]': [f64; 2]
372 130..171 '{ ... }': ()
380 fn infer_adt_pattern() {
391 let e = E::A { x: 3 };
394 let E::A { x: new_var } = e;
402 let ref d @ E::A { .. } = e;
407 67..288 '{ ... d; }': ()
409 81..94 'E::A { x: 3 }': E
411 105..112 'S(y, z)': S
415 128..147 'E::A {..._var }': E
416 138..145 'new_var': usize
418 158..244 'match ... }': usize
420 176..186 'E::A { x }': E
428 255..274 'ref d ...{ .. }': &E
429 263..274 'E::A { .. }': E
437 fn enum_variant_through_self_in_pattern() {
449 Self::A { x } => { x; },
450 Self::B(x) => { x; },
457 75..217 '{ ... }': ()
458 85..210 'match ... }': ()
461 115..128 'Self::A { x }': E
463 132..138 '{ x; }': ()
465 152..162 'Self::B(x)': E
467 166..172 '{ x; }': ()
469 186..193 'Self::C': E
476 fn infer_generics_in_patterns() {
488 fn test(a1: A<u32>, o: Option<u64>) {
489 let A { x: x2 } = a1;
490 let A::<i64> { x: x3 } = A { x: 1 };
492 Option::Some(t) => t,
499 90..91 'o': Option<u64>
500 106..243 '{ ... }; }': ()
501 116..127 'A { x: x2 }': A<u32>
503 130..132 'a1': A<u32>
504 142..160 'A::<i6...: x3 }': A<i64>
506 163..173 'A { x: 1 }': A<i64>
508 179..240 'match ... }': u64
509 185..186 'o': Option<u64>
510 197..212 'Option::Some(t)': Option<u64>
513 227..228 '_': Option<u64>
520 fn infer_const_pattern() {
523 enum Option<T> { None }
526 const Bar: usize = 1;
529 let a: Option<u32> = None;
530 let b: Option<i64> = match a {
533 let _: () = match () { Foo => () };
534 // ^^^ expected (), got Foo
535 let _: () = match () { Bar => () };
536 // ^^^ expected (), got usize
547 impl S { fn foo(&self) -> bool { false } }
557 41..50 '{ false }': bool
559 64..115 '{ ... } }': ()
560 70..113 'match ... }': ()
564 93..100 's.foo()': bool
571 fn match_ergonomics_in_closure_params() {
575 fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
578 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
579 foo(&(1, "a"), |(x, y)| x);
585 49..60 '{ loop {} }': U
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)
595 93..104 '|&(x, y)| x': |&(i32, &str)| -> i32
596 94..101 '&(x, y)': &(i32, &str)
597 95..101 '(x, y)': (i32, &str)
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)
607 157..167 '|(x, y)| x': |&(i32, &str)| -> &i32
608 158..164 '(x, y)': (i32, &str)
617 fn slice_tail_pattern() {
620 fn foo(params: &[i32]) {
622 [head, tail @ ..] => {
628 7..13 'params': &[i32]
629 23..92 '{ ... } }': ()
630 29..90 'match ... }': ()
631 35..41 'params': &[i32]
632 52..69 '[head,... @ ..]': [i32]
634 59..68 'tail @ ..': &[i32]
646 #[lang = "owned_box"]
647 pub struct Box<T, A = Global>(T);
649 fn foo(params: Box<i32>) {
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
667 #[lang = "owned_box"]
668 pub struct Box<T>(T);
670 fn foo(params: Box<i32>) {
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
689 fn tuple_ellipsis_pattern() {
690 check_infer_with_mismatches(
692 fn foo(tuple: (u8, i16, f32)) {
697 (a, b) => {/*too short*/}
698 (a, b, c, d) => {/*too long*/}
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)
711 84..94 '(a, .., c)': (u8, i16, f32)
715 110..120 '(a, b, ..)': (u8, i16, f32)
719 136..142 '(a, b)': (u8, i16)
722 146..161 '{/*too short*/}': ()
723 170..182 '(a, b, c, d)': (u8, i16, f32, {unknown})
727 180..181 'd': {unknown}
728 186..200 '{/*too long*/}': ()
729 209..210 '_': (u8, i16, f32)
731 136..142: expected (u8, i16, f32), got (u8, i16)
732 170..182: expected (u8, i16, f32), got (u8, i16, f32, {unknown})
738 fn tuple_struct_ellipsis_pattern() {
741 struct Tuple(u8, i16, f32);
742 fn foo(tuple: 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*/}
753 35..40 'tuple': Tuple
754 49..268 '{ ... } }': ()
755 55..266 'match ... }': ()
756 61..66 'tuple': Tuple
757 77..92 'Tuple(.., b, c)': Tuple
761 108..123 'Tuple(a, .., c)': Tuple
765 139..154 'Tuple(a, b, ..)': Tuple
769 170..181 'Tuple(a, b)': Tuple
772 185..200 '{/*too short*/}': ()
773 209..226 'Tuple(... c, d)': Tuple
777 224..225 'd': {unknown}
778 230..244 '{/*too long*/}': ()
786 fn const_block_pattern() {
792 const { Foo(15 + 32) } => {},
798 36..115 '{ ... } }': ()
799 42..113 'match ... }': ()
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
806 74..81 '15 + 32': usize
820 ($name:ident) => { Enum::Variant1($name) }
842 fn type_mismatch_in_or_pattern() {
843 check_infer_with_mismatches(
855 10..142 '{ ... } }': ()
856 16..140 'match ... }': ()
857 22..30 '(false,)': (bool,)
859 41..53 '(true | (),)': (bool,)
862 42..51 'true | ()': bool
865 68..80 '(() | true,)': ((),)
867 69..78 '() | true': ()
871 95..104 '(_ | (),)': (bool,)
873 96..102 '_ | ()': bool
876 119..128 '(() | _,)': ((),)
878 120..126 '() | _': ()
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 ()
894 fn pattern_lookup_in_value_ns() {
897 use self::Constructor::*;
905 match Constructor::IntRange(IntRange { range: () }) {
910 Constructor::IntRange(x) => {
926 opt if let (x,) = opt => {