1 use expect_test::expect;
3 use super::{check_infer, check_infer_with_mismatches};
13 let (c, d) = (1, "hello");
15 for (e, f) in some_iter {
23 let lambda = |a: u64, b, c: i32| { a + b; c };
27 let ref mut mut_ref_to_x = x;
33 17..368 '{ ...o_x; }': ()
41 73..79 '(c, d)': (i32, &str)
44 82..94 '(1, "hello")': (i32, &str)
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
67 243..255 '{ a + b; c }': i32
72 266..278 'ref ref_to_x': &&i32
74 292..301 'mut mut_x': &i32
76 315..335 'ref mu...f_to_x': &mut &i32
78 349..350 'k': &mut &i32
79 353..365 'mut_ref_to_x': &mut &i32
85 fn infer_literal_pattern() {
86 check_infer_with_mismatches(
88 fn any<T>() -> T { loop {} }
90 if let "foo" = any() {}
92 if let 1u32 = any() {}
93 if let 1f32 = any() {}
95 if let true = any() {}
99 17..28 '{ loop {} }': T
103 46..208 '{ ...) {} }': ()
104 52..75 'if let...y() {}': ()
107 67..70 'any': fn any<&str>() -> &str
110 80..99 'if let...y() {}': ()
113 91..94 'any': fn any<i32>() -> i32
116 104..126 'if let...y() {}': ()
119 118..121 'any': fn any<u32>() -> u32
120 118..123 'any()': u32
122 131..153 'if let...y() {}': ()
125 145..148 'any': fn any<f32>() -> f32
126 145..150 'any()': f32
128 158..179 'if let...y() {}': ()
131 171..174 'any': fn any<f64>() -> f64
132 171..176 'any()': f64
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
145 fn infer_range_pattern() {
146 check_infer_with_mismatches(
149 if let 1..76 = 2u32 {}
150 if let 1..=76 = 2u32 {}
155 17..75 '{ ...2 {} }': ()
156 23..45 'if let...u32 {}': ()
160 50..73 'if let...u32 {}': ()
169 fn infer_pattern_match_ergonomics() {
176 let A(n) = &mut A(1);
180 27..78 '{ ...(1); }': ()
181 37..41 'A(n)': A<i32>
183 44..49 '&A(1)': &A<i32>
184 45..46 'A': A<i32>(i32) -> A<i32>
185 45..49 'A(1)': A<i32>
187 59..63 'A(n)': A<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>
198 fn infer_pattern_match_ergonomics_ref() {
199 cov_mark::check!(match_ergonomics_ref);
208 10..56 '{ ...= v; }': ()
209 20..21 'v': &(i32, &i32)
210 24..32 '&(1, &2)': &(i32, &i32)
211 25..32 '(1, &2)': (i32, &i32)
215 42..49 '(_, &w)': (i32, &i32)
219 52..53 'v': &(i32, &i32)
225 fn infer_pattern_match_slice() {
229 let slice: &[f64] = &[0.0];
244 10..209 '{ ... } }': ()
245 20..25 'slice': &[f64]
246 36..42 '&[0.0]': &[f64; _]
247 37..42 '[0.0]': [f64; _]
249 48..207 'match ... }': ()
250 54..59 'slice': &[f64]
254 89..93 '&[a]': &[f64]
257 97..123 '{ ... }': ()
259 133..140 '&[b, c]': &[f64]
260 134..140 '[b, c]': [f64]
263 144..185 '{ ... }': ()
273 fn infer_pattern_match_string_literal() {
274 check_infer_with_mismatches(
277 let s: &str = "hello";
285 10..98 '{ ... } }': ()
287 30..37 '"hello"': &str
288 43..96 'match ... }': ()
290 61..68 '"hello"': &str
291 61..68 '"hello"': &str
300 fn infer_pattern_match_or() {
301 check_infer_with_mismatches(
304 let s: &str = "hello";
306 "hello" | "world" => {}
312 10..108 '{ ... } }': ()
314 30..37 '"hello"': &str
315 43..106 'match ... }': ()
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
330 fn infer_pattern_match_arr() {
334 let arr: [f64; 2] = [0.0, 1.0];
347 10..179 '{ ... } }': ()
348 20..23 'arr': [f64; _]
349 36..46 '[0.0, 1.0]': [f64; _]
352 52..177 'match ... }': ()
353 58..61 'arr': [f64; _]
354 72..80 '[1.0, a]': [f64; _]
358 84..110 '{ ... }': ()
360 120..126 '[b, c]': [f64; _]
363 130..171 '{ ... }': ()
371 fn infer_adt_pattern() {
382 let e = E::A { x: 3 };
385 let E::A { x: new_var } = e;
393 let ref d @ E::A { .. } = e;
398 67..288 '{ ... d; }': ()
400 81..94 'E::A { x: 3 }': E
402 105..112 'S(y, z)': S
406 128..147 'E::A {..._var }': E
407 138..145 'new_var': usize
409 158..244 'match ... }': usize
411 176..186 'E::A { x }': E
419 255..274 'ref d ...{ .. }': &E
420 263..274 'E::A { .. }': E
428 fn enum_variant_through_self_in_pattern() {
440 Self::A { x } => { x; },
441 Self::B(x) => { x; },
448 75..217 '{ ... }': ()
449 85..210 'match ... }': ()
452 115..128 'Self::A { x }': E
454 132..138 '{ x; }': ()
456 152..162 'Self::B(x)': E
458 166..172 '{ x; }': ()
460 186..193 'Self::C': E
467 fn infer_generics_in_patterns() {
479 fn test(a1: A<u32>, o: Option<u64>) {
480 let A { x: x2 } = a1;
481 let A::<i64> { x: x3 } = A { x: 1 };
483 Option::Some(t) => t,
490 90..91 'o': Option<u64>
491 106..243 '{ ... }; }': ()
492 116..127 'A { x: x2 }': A<u32>
494 130..132 'a1': A<u32>
495 142..160 'A::<i6...: x3 }': A<i64>
497 163..173 'A { x: 1 }': A<i64>
499 179..240 'match ... }': u64
500 185..186 'o': Option<u64>
501 197..212 'Option::Some(t)': Option<u64>
504 227..228 '_': Option<u64>
511 fn infer_const_pattern() {
512 check_infer_with_mismatches(
514 enum Option<T> { None }
517 const Bar: usize = 1;
520 let a: Option<u32> = None;
521 let b: Option<i64> = match a {
524 let _: () = match () { Foo => Foo }; // Expected mismatch
525 let _: () = match () { Bar => Bar }; // Expected mismatch
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>
539 200..223 'match ... Foo }': Foo
544 262..285 'match ... Bar }': usize
546 273..276 'Bar': usize
547 280..283 'Bar': usize
548 200..223: expected (), got Foo
549 262..285: expected (), got usize
559 impl S { fn foo(&self) -> bool { false } }
569 41..50 '{ false }': bool
571 64..115 '{ ... } }': ()
572 70..113 'match ... }': ()
576 93..100 's.foo()': bool
583 fn match_ergonomics_in_closure_params() {
591 fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
594 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
595 foo(&(1, "a"), |(x, y)| x);
601 110..121 '{ loop {} }': U
602 112..119 'loop {}': !
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)
611 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32
612 155..162 '&(x, y)': &(i32, &str)
613 156..162 '(x, y)': (i32, &str)
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)
623 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32
624 219..225 '(x, y)': (i32, &str)
633 fn slice_tail_pattern() {
636 fn foo(params: &[i32]) {
638 [head, tail @ ..] => {
644 7..13 'params': &[i32]
645 23..92 '{ ... } }': ()
646 29..90 'match ... }': ()
647 35..41 'params': &[i32]
648 52..69 '[head,... @ ..]': [i32]
650 59..68 'tail @ ..': &[i32]
662 #[lang = "owned_box"]
663 pub struct Box<T, A = Global>(T);
665 fn foo(params: Box<i32>) {
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
683 #[lang = "owned_box"]
684 pub struct Box<T>(T);
686 fn foo(params: Box<i32>) {
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
705 fn tuple_ellipsis_pattern() {
708 fn foo(tuple: (u8, i16, f32)) {
713 (a, b) => {/*too short*/}
714 (a, b, c, d) => {/*too long*/}
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)
727 84..94 '(a, .., c)': (u8, i16, f32)
731 110..120 '(a, b, ..)': (u8, i16, f32)
735 136..142 '(a, b)': (u8, i16, f32)
738 146..161 '{/*too short*/}': ()
739 170..182 '(a, b, c, d)': (u8, i16, f32, {unknown})
743 180..181 'd': {unknown}
744 186..200 '{/*too long*/}': ()
745 209..210 '_': (u8, i16, f32)
752 fn tuple_struct_ellipsis_pattern() {
755 struct Tuple(u8, i16, f32);
756 fn foo(tuple: 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*/}
767 35..40 'tuple': Tuple
768 49..268 '{ ... } }': ()
769 55..266 'match ... }': ()
770 61..66 'tuple': Tuple
771 77..92 'Tuple(.., b, c)': Tuple
775 108..123 'Tuple(a, .., c)': Tuple
779 139..154 'Tuple(a, b, ..)': Tuple
783 170..181 'Tuple(a, b)': Tuple
786 185..200 '{/*too short*/}': ()
787 209..226 'Tuple(... c, d)': Tuple
791 224..225 'd': {unknown}
792 230..244 '{/*too long*/}': ()
800 fn const_block_pattern() {
806 const { Foo(15 + 32) } => {},
812 36..115 '{ ... } }': ()
813 42..113 'match ... }': ()
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
820 74..81 '15 + 32': usize