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 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
70 228..233 '&true': &bool
73 246..252 'lambda': |u64, u64, i32| -> i32
74 255..287 '|a: u6...b; c }': |u64, u64, i32| -> i32
78 275..287 '{ a + b; c }': i32
83 298..310 'ref ref_to_x': &&i32
85 324..333 'mut mut_x': &i32
87 347..367 'ref mu...f_to_x': &mut &i32
89 381..382 'k': &mut &i32
90 385..397 'mut_ref_to_x': &mut &i32
96 fn infer_literal_pattern() {
97 check_infer_with_mismatches(
99 fn any<T>() -> T { loop {} }
101 if let "foo" = any() {}
103 if let 1u32 = any() {}
104 if let 1f32 = any() {}
105 if let 1.0 = any() {}
106 if let true = any() {}
110 17..28 '{ loop {} }': T
114 46..208 '{ ...) {} }': ()
115 52..75 'if let...y() {}': ()
116 55..72 'let "f... any()': bool
119 67..70 'any'
: fn any
<&str>() -> &str
122 80..99 '
if let...y() {}'
: ()
123 83..96 '
let 1 = any()'
: bool
126 91..94 'any'
: fn any
<i32>() -> i32
129 104..126 '
if let...y() {}'
: ()
130 107..123 '
let 1u... any()'
: bool
133 118..121 'any'
: fn any
<u32>() -> u32
134 118..123 '
any()'
: u32
136 131..153 '
if let...y() {}'
: ()
137 134..150 '
let 1f... any()'
: bool
140 145..148 'any'
: fn any
<f32>() -> f32
141 145..150 '
any()'
: f32
143 158..179 '
if let...y() {}'
: ()
144 161..176 '
let 1.0 = any()'
: bool
147 171..174 'any'
: fn any
<f64>() -> f64
148 171..176 '
any()'
: f64
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
162 fn infer_range_pattern() {
163 check_infer_with_mismatches(
166 if let 1..76 = 2u32 {}
167 if let 1..=76 = 2u32 {}
172 17..75 '{ ...2 {}
}'
: ()
173 23..45 '
if let...u32 {}'
: ()
174 26..42 '
let 1....= 2u32'
: bool
178 50..73 '
if let...u32 {}'
: ()
179 53..70 '
let 1....= 2u32'
: bool
188 fn infer_pattern_match_ergonomics() {
195 let A(n
) = &mut A(1);
199 27..78 '{ ...(1); }'
: ()
200 37..41 '
A(n
)'
: A
<i32>
202 44..49 '
&A(1)'
: &A
<i32>
203 45..46 'A'
: A
<i32>(i32) -> A
<i32>
204 45..49 '
A(1)'
: A
<i32>
206 59..63 '
A(n
)'
: A
<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>
217 fn infer_pattern_match_ergonomics_ref() {
218 cov_mark::check!(match_ergonomics_ref);
227 10..56 '{ ...= v; }'
: ()
228 20..21 'v'
: &(i32, &i32)
229 24..32 '
&(1, &2)'
: &(i32, &i32)
230 25..32 '
(1, &2)'
: (i32, &i32)
234 42..49 '
(_
, &w
)'
: (i32, &i32)
238 52..53 'v'
: &(i32, &i32)
244 fn infer_pattern_match_slice() {
248 let slice
: &[f64] = &[0.0];
263 10..209 '{ ... }
}'
: ()
264 20..25 'slice'
: &[f64]
265 36..42 '
&[0.0]'
: &[f64; 1]
266 37..42 '
[0.0]'
: [f64; 1]
268 48..207 '
match ... }'
: ()
269 54..59 'slice'
: &[f64]
273 89..93 '
&[a
]'
: &[f64]
276 97..123 '{ ... }'
: ()
278 133..140 '
&[b
, c
]'
: &[f64]
279 134..140 '
[b
, c
]'
: [f64]
282 144..185 '{ ... }'
: ()
292 fn infer_pattern_match_string_literal() {
293 check_infer_with_mismatches(
296 let s
: &str = "hello";
304 10..98 '{ ... }
}'
: ()
306 30..37 '
"hello"'
: &str
307 43..96 '
match ... }'
: ()
309 61..68 '
"hello"'
: &str
310 61..68 '
"hello"'
: &str
319 fn infer_pattern_match_byte_string_literal() {
320 check_infer_with_mismatches(
324 impl<T
, const N
: usize> core
::ops
::Index
<S
> for [T
; N
] {
326 fn index(&self, index
: core
::ops
::RangeFull
) -> &Self::Output
{
330 fn test(v
: [u8; 3]) {
331 if let b
"foo" = &v
[S
] {}
332 if let b
"foo" = &v {}
336 105..109 '
self'
: &[T
; N
]
337 111..116 'index'
: {unknown}
338 157..180 '{ ... }'
: &[u8]
339 167..174 '
loop {}'
: !
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]
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]
364 fn infer_pattern_match_or() {
365 check_infer_with_mismatches(
368 let s: &str = "hello";
370 "hello" | "world" => {}
376 10..108 '{ ... } }': ()
378 30..37 '"hello"': &str
379 43..106 'match ... }': ()
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
394 fn infer_pattern_match_arr() {
398 let arr: [f64; 2] = [0.0, 1.0];
411 10..179 '{ ... } }': ()
412 20..23 'arr': [f64; 2]
413 36..46 '[0.0, 1.0]': [f64; 2]
416 52..177 'match ... }': ()
417 58..61 'arr': [f64; 2]
418 72..80 '[1.0, a]': [f64; 2]
422 84..110 '{ ... }': ()
424 120..126 '[b, c]': [f64; 2]
427 130..171 '{ ... }': ()
435 fn infer_adt_pattern() {
446 let e = E::A { x: 3 };
449 let E::A { x: new_var } = e;
457 let ref d @ E::A { .. } = e;
462 67..288 '{ ... d; }': ()
464 81..94 'E::A { x: 3 }': E
466 105..112 'S(y, z)': S
470 128..147 'E::A {..._var }': E
471 138..145 'new_var': usize
473 158..244 'match ... }': usize
475 176..186 'E::A { x }': E
483 255..274 'ref d ...{ .. }': &E
484 263..274 'E::A { .. }': E
492 fn tuple_struct_destructured_with_self() {
498 let Self(s,) = &Foo(0,);
499 let Self(s,) = &mut Foo(0,);
500 let Self(s,) = Foo(0,);
505 42..151 '{ ... }': ()
506 56..64 'Self(s,)': Foo
508 67..75 '&Foo(0,)': &Foo
509 68..71 'Foo': Foo(usize) -> Foo
510 68..75 'Foo(0,)': Foo
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
518 126..134 'Self(s,)': Foo
520 137..140 'Foo': Foo(usize) -> Foo
521 137..144 'Foo(0,)': Foo
528 fn enum_variant_through_self_in_pattern() {
540 Self::A { x } => { x; },
541 Self::B(x) => { x; },
548 75..217 '{ ... }': ()
549 85..210 'match ... }': ()
552 115..128 'Self::A { x }': E
554 132..138 '{ x; }': ()
556 152..162 'Self::B(x)': E
558 166..172 '{ x; }': ()
560 186..193 'Self::C': E
567 fn infer_generics_in_patterns() {
579 fn test(a1: A<u32>, o: Option<u64>) {
580 let A { x: x2 } = a1;
581 let A::<i64> { x: x3 } = A { x: 1 };
583 Option::Some(t) => t,
590 90..91 'o': Option<u64>
591 106..243 '{ ... }; }': ()
592 116..127 'A { x: x2 }': A<u32>
594 130..132 'a1': A<u32>
595 142..160 'A::<i6...: x3 }': A<i64>
597 163..173 'A { x: 1 }': A<i64>
599 179..240 'match ... }': u64
600 185..186 'o': Option<u64>
601 197..212 'Option::Some(t)': Option<u64>
604 227..228 '_': Option<u64>
611 fn infer_const_pattern() {
614 enum Option<T> { None }
617 const Bar: usize = 1;
620 let a: Option<u32> = None;
621 let b: Option<i64> = match a {
624 let _: () = match () { Foo => () };
625 // ^^^ expected (), got Foo
626 let _: () = match () { Bar => () };
627 // ^^^ expected (), got usize
638 impl S { fn foo(&self) -> bool { false } }
648 41..50 '{ false }': bool
650 64..115 '{ ... } }': ()
651 70..113 'match ... }': ()
655 93..100 's.foo()': bool
662 fn match_ergonomics_in_closure_params() {
666 fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
669 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
670 foo(&(1, "a"), |(x, y)| x);
676 49..60 '{ loop {} }': U
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)
686 93..104 '|&(x, y)| x': |&(i32, &str)| -> i32
687 94..101 '&(x, y)': &(i32, &str)
688 95..101 '(x, y)': (i32, &str)
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)
698 157..167 '|(x, y)| x': |&(i32, &str)| -> &i32
699 158..164 '(x, y)': (i32, &str)
708 fn slice_tail_pattern() {
711 fn foo(params: &[i32]) {
713 [head, tail @ ..] => {
719 7..13 'params': &[i32]
720 23..92 '{ ... } }': ()
721 29..90 'match ... }': ()
722 35..41 'params': &[i32]
723 52..69 '[head,... @ ..]': [i32]
725 59..68 'tail @ ..': &[i32]
737 #[lang = "owned_box"]
738 pub struct Box<T, A = Global>(T);
740 fn foo(params: Box<i32>) {
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
758 #[lang = "owned_box"]
759 pub struct Box<T>(T);
761 fn foo(params: Box<i32>) {
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
780 fn tuple_ellipsis_pattern() {
781 check_infer_with_mismatches(
783 fn foo(tuple: (u8, i16, f32)) {
788 (a, b) => {/*too short*/}
789 (a, b, c, d) => {/*too long*/}
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)
802 84..94 '(a, .., c)': (u8, i16, f32)
806 110..120 '(a, b, ..)': (u8, i16, f32)
810 136..142 '(a, b)': (u8, i16)
813 146..161 '{/*too short*/}': ()
814 170..182 '(a, b, c, d)': (u8, i16, f32, {unknown})
818 180..181 'd': {unknown}
819 186..200 '{/*too long*/}': ()
820 209..210 '_': (u8, i16, f32)
822 136..142: expected (u8, i16, f32), got (u8, i16)
823 170..182: expected (u8, i16, f32), got (u8, i16, f32, {unknown})
829 fn tuple_struct_ellipsis_pattern() {
832 struct Tuple(u8, i16, f32);
833 fn foo(tuple: 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*/}
844 35..40 'tuple': Tuple
845 49..268 '{ ... } }': ()
846 55..266 'match ... }': ()
847 61..66 'tuple': Tuple
848 77..92 'Tuple(.., b, c)': Tuple
852 108..123 'Tuple(a, .., c)': Tuple
856 139..154 'Tuple(a, b, ..)': Tuple
860 170..181 'Tuple(a, b)': Tuple
863 185..200 '{/*too short*/}': ()
864 209..226 'Tuple(... c, d)': Tuple
868 224..225 'd': {unknown}
869 230..244 '{/*too long*/}': ()
877 fn const_block_pattern() {
883 const { Foo(15 + 32) } => {},
889 36..115 '{ ... } }': ()
890 42..113 'match ... }': ()
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
897 74..81 '15 + 32': usize
911 ($name:ident) => { Enum::Variant1($name) }
933 fn type_mismatch_in_or_pattern() {
934 check_infer_with_mismatches(
946 10..142 '{ ... } }': ()
947 16..140 'match ... }': ()
948 22..30 '(false,)': (bool,)
950 41..53 '(true | (),)': (bool,)
953 42..51 'true | ()': bool
956 68..80 '(() | true,)': ((),)
958 69..78 '() | true': ()
962 95..104 '(_ | (),)': (bool,)
964 96..102 '_ | ()': bool
967 119..128 '(() | _,)': ((),)
969 120..126 '() | _': ()
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 ()
985 fn slice_pattern_correctly_handles_array_length() {
989 let [head, middle @ .., tail, tail2] = [1, 2, 3, 4, 5];
993 10..73 '{ ... 5]; }': ()
994 20..52 '[head,...tail2]': [i32; 5]
996 27..38 'middle @ ..': [i32; 2]
997 36..38 '..': [i32; 2]
1000 55..70 '[1, 2, 3, 4, 5]': [i32; 5]
1011 fn pattern_lookup_in_value_ns() {
1014 use self::Constructor::*;
1022 match Constructor::IntRange(IntRange { range: () }) {
1027 Constructor::IntRange(x) => {
1038 fn if_let_guards() {
1043 opt if let (x,) = opt => {
1055 fn tuple_wildcard() {
1059 enum Option<T> {Some(T), None}
1064 //^ Option<(i32, i32)>
1066 if let Some((_, _a)) = x {}
1078 fn my_fn(#[cfg(feature = "feature")] u8: u8, u32: u32) {}