2019-12-03 12:38:54 +00:00
|
|
|
use insta::assert_snapshot;
|
|
|
|
use test_utils::covers;
|
|
|
|
|
2020-04-11 21:33:17 +00:00
|
|
|
use super::{infer, infer_with_mismatches};
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_pattern() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
fn test(x: &i32) {
|
|
|
|
let y = x;
|
|
|
|
let &z = x;
|
|
|
|
let a = z;
|
|
|
|
let (c, d) = (1, "hello");
|
|
|
|
|
|
|
|
for (e, f) in some_iter {
|
|
|
|
let g = e;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let [val] = opt {
|
|
|
|
let h = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
let lambda = |a: u64, b, c: i32| { a + b; c };
|
|
|
|
|
|
|
|
let ref ref_to_x = x;
|
|
|
|
let mut mut_x = x;
|
|
|
|
let ref mut mut_ref_to_x = x;
|
|
|
|
let k = mut_ref_to_x;
|
|
|
|
}
|
|
|
|
"#),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
9..10 'x': &i32
|
|
|
|
18..369 '{ ...o_x; }': ()
|
|
|
|
28..29 'y': &i32
|
|
|
|
32..33 'x': &i32
|
|
|
|
43..45 '&z': &i32
|
|
|
|
44..45 'z': i32
|
|
|
|
48..49 'x': &i32
|
|
|
|
59..60 'a': i32
|
|
|
|
63..64 'z': i32
|
|
|
|
74..80 '(c, d)': (i32, &str)
|
|
|
|
75..76 'c': i32
|
|
|
|
78..79 'd': &str
|
|
|
|
83..95 '(1, "hello")': (i32, &str)
|
|
|
|
84..85 '1': i32
|
|
|
|
87..94 '"hello"': &str
|
|
|
|
102..152 'for (e... }': ()
|
|
|
|
106..112 '(e, f)': ({unknown}, {unknown})
|
|
|
|
107..108 'e': {unknown}
|
|
|
|
110..111 'f': {unknown}
|
|
|
|
116..125 'some_iter': {unknown}
|
|
|
|
126..152 '{ ... }': ()
|
|
|
|
140..141 'g': {unknown}
|
|
|
|
144..145 'e': {unknown}
|
|
|
|
158..205 'if let... }': ()
|
|
|
|
165..170 '[val]': [{unknown}]
|
|
|
|
166..169 'val': {unknown}
|
|
|
|
173..176 'opt': [{unknown}]
|
|
|
|
177..205 '{ ... }': ()
|
|
|
|
191..192 'h': {unknown}
|
|
|
|
195..198 'val': {unknown}
|
|
|
|
215..221 'lambda': |u64, u64, i32| -> i32
|
|
|
|
224..256 '|a: u6...b; c }': |u64, u64, i32| -> i32
|
|
|
|
225..226 'a': u64
|
|
|
|
233..234 'b': u64
|
|
|
|
236..237 'c': i32
|
|
|
|
244..256 '{ a + b; c }': i32
|
|
|
|
246..247 'a': u64
|
|
|
|
246..251 'a + b': u64
|
|
|
|
250..251 'b': u64
|
|
|
|
253..254 'c': i32
|
|
|
|
267..279 'ref ref_to_x': &&i32
|
|
|
|
282..283 'x': &i32
|
|
|
|
293..302 'mut mut_x': &i32
|
|
|
|
305..306 'x': &i32
|
|
|
|
316..336 'ref mu...f_to_x': &mut &i32
|
|
|
|
339..340 'x': &i32
|
|
|
|
350..351 'k': &mut &i32
|
|
|
|
354..366 'mut_ref_to_x': &mut &i32
|
2019-12-03 12:38:54 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-04-01 18:27:47 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_literal_pattern() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer_with_mismatches(r#"
|
|
|
|
fn any<T>() -> T { loop {} }
|
|
|
|
fn test(x: &i32) {
|
|
|
|
if let "foo" = any() {}
|
|
|
|
if let 1 = any() {}
|
|
|
|
if let 1u32 = any() {}
|
|
|
|
if let 1f32 = any() {}
|
|
|
|
if let 1.0 = any() {}
|
|
|
|
if let true = any() {}
|
|
|
|
}
|
|
|
|
"#, true),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
18..29 '{ loop {} }': T
|
|
|
|
20..27 'loop {}': !
|
|
|
|
25..27 '{}': ()
|
|
|
|
38..39 'x': &i32
|
|
|
|
47..209 '{ ...) {} }': ()
|
|
|
|
53..76 'if let...y() {}': ()
|
|
|
|
60..65 '"foo"': &str
|
|
|
|
60..65 '"foo"': &str
|
|
|
|
68..71 'any': fn any<&str>() -> &str
|
|
|
|
68..73 'any()': &str
|
|
|
|
74..76 '{}': ()
|
|
|
|
81..100 'if let...y() {}': ()
|
|
|
|
88..89 '1': i32
|
|
|
|
88..89 '1': i32
|
|
|
|
92..95 'any': fn any<i32>() -> i32
|
|
|
|
92..97 'any()': i32
|
|
|
|
98..100 '{}': ()
|
|
|
|
105..127 'if let...y() {}': ()
|
|
|
|
112..116 '1u32': u32
|
|
|
|
112..116 '1u32': u32
|
|
|
|
119..122 'any': fn any<u32>() -> u32
|
|
|
|
119..124 'any()': u32
|
|
|
|
125..127 '{}': ()
|
|
|
|
132..154 'if let...y() {}': ()
|
|
|
|
139..143 '1f32': f32
|
|
|
|
139..143 '1f32': f32
|
|
|
|
146..149 'any': fn any<f32>() -> f32
|
|
|
|
146..151 'any()': f32
|
|
|
|
152..154 '{}': ()
|
|
|
|
159..180 'if let...y() {}': ()
|
|
|
|
166..169 '1.0': f64
|
|
|
|
166..169 '1.0': f64
|
|
|
|
172..175 'any': fn any<f64>() -> f64
|
|
|
|
172..177 'any()': f64
|
|
|
|
178..180 '{}': ()
|
|
|
|
185..207 'if let...y() {}': ()
|
|
|
|
192..196 'true': bool
|
|
|
|
192..196 'true': bool
|
|
|
|
199..202 'any': fn any<bool>() -> bool
|
|
|
|
199..204 'any()': bool
|
|
|
|
205..207 '{}': ()
|
2020-04-01 18:27:47 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_range_pattern() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer_with_mismatches(r#"
|
|
|
|
fn test(x: &i32) {
|
|
|
|
if let 1..76 = 2u32 {}
|
|
|
|
if let 1..=76 = 2u32 {}
|
|
|
|
}
|
|
|
|
"#, true),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
9..10 'x': &i32
|
|
|
|
18..76 '{ ...2 {} }': ()
|
|
|
|
24..46 'if let...u32 {}': ()
|
|
|
|
31..36 '1..76': u32
|
|
|
|
39..43 '2u32': u32
|
|
|
|
44..46 '{}': ()
|
|
|
|
51..74 'if let...u32 {}': ()
|
|
|
|
58..64 '1..=76': u32
|
|
|
|
67..71 '2u32': u32
|
|
|
|
72..74 '{}': ()
|
2020-04-01 18:27:47 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_pattern_match_ergonomics() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
struct A<T>(T);
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let A(n) = &A(1);
|
|
|
|
let A(n) = &mut A(1);
|
|
|
|
}
|
|
|
|
"#),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
28..79 '{ ...(1); }': ()
|
|
|
|
38..42 'A(n)': A<i32>
|
|
|
|
40..41 'n': &i32
|
|
|
|
45..50 '&A(1)': &A<i32>
|
|
|
|
46..47 'A': A<i32>(i32) -> A<i32>
|
|
|
|
46..50 'A(1)': A<i32>
|
|
|
|
48..49 '1': i32
|
|
|
|
60..64 'A(n)': A<i32>
|
|
|
|
62..63 'n': &mut i32
|
|
|
|
67..76 '&mut A(1)': &mut A<i32>
|
|
|
|
72..73 'A': A<i32>(i32) -> A<i32>
|
|
|
|
72..76 'A(1)': A<i32>
|
|
|
|
74..75 '1': i32
|
2019-12-03 12:38:54 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_pattern_match_ergonomics_ref() {
|
|
|
|
covers!(match_ergonomics_ref);
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
fn test() {
|
|
|
|
let v = &(1, &2);
|
|
|
|
let (_, &w) = v;
|
|
|
|
}
|
|
|
|
"#),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
11..57 '{ ...= v; }': ()
|
|
|
|
21..22 'v': &(i32, &i32)
|
|
|
|
25..33 '&(1, &2)': &(i32, &i32)
|
|
|
|
26..33 '(1, &2)': (i32, &i32)
|
|
|
|
27..28 '1': i32
|
|
|
|
30..32 '&2': &i32
|
|
|
|
31..32 '2': i32
|
|
|
|
43..50 '(_, &w)': (i32, &i32)
|
|
|
|
44..45 '_': i32
|
|
|
|
47..49 '&w': &i32
|
|
|
|
48..49 'w': i32
|
|
|
|
53..54 'v': &(i32, &i32)
|
2019-12-03 12:38:54 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-03-01 14:25:38 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_pattern_match_slice() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
fn test() {
|
|
|
|
let slice: &[f64] = &[0.0];
|
|
|
|
match slice {
|
2020-03-01 15:08:05 +00:00
|
|
|
&[] => {},
|
2020-03-01 14:25:38 +00:00
|
|
|
&[a] => {
|
|
|
|
a;
|
2020-03-01 15:08:05 +00:00
|
|
|
},
|
|
|
|
&[b, c] => {
|
|
|
|
b;
|
|
|
|
c;
|
2020-03-01 14:25:38 +00:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
11..210 '{ ... } }': ()
|
|
|
|
21..26 'slice': &[f64]
|
|
|
|
37..43 '&[0.0]': &[f64; _]
|
|
|
|
38..43 '[0.0]': [f64; _]
|
|
|
|
39..42 '0.0': f64
|
|
|
|
49..208 'match ... }': ()
|
|
|
|
55..60 'slice': &[f64]
|
|
|
|
71..74 '&[]': &[f64]
|
|
|
|
72..74 '[]': [f64]
|
|
|
|
78..80 '{}': ()
|
|
|
|
90..94 '&[a]': &[f64]
|
|
|
|
91..94 '[a]': [f64]
|
|
|
|
92..93 'a': f64
|
|
|
|
98..124 '{ ... }': ()
|
|
|
|
112..113 'a': f64
|
|
|
|
134..141 '&[b, c]': &[f64]
|
|
|
|
135..141 '[b, c]': [f64]
|
|
|
|
136..137 'b': f64
|
|
|
|
139..140 'c': f64
|
|
|
|
145..186 '{ ... }': ()
|
|
|
|
159..160 'b': f64
|
|
|
|
174..175 'c': f64
|
|
|
|
195..196 '_': &[f64]
|
|
|
|
200..202 '{}': ()
|
2020-03-01 14:25:38 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-03-01 22:02:32 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_pattern_match_arr() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
fn test() {
|
|
|
|
let arr: [f64; 2] = [0.0, 1.0];
|
|
|
|
match arr {
|
|
|
|
[1.0, a] => {
|
|
|
|
a;
|
|
|
|
},
|
|
|
|
[b, c] => {
|
|
|
|
b;
|
|
|
|
c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
11..180 '{ ... } }': ()
|
|
|
|
21..24 'arr': [f64; _]
|
|
|
|
37..47 '[0.0, 1.0]': [f64; _]
|
|
|
|
38..41 '0.0': f64
|
|
|
|
43..46 '1.0': f64
|
|
|
|
53..178 'match ... }': ()
|
|
|
|
59..62 'arr': [f64; _]
|
|
|
|
73..81 '[1.0, a]': [f64; _]
|
|
|
|
74..77 '1.0': f64
|
|
|
|
74..77 '1.0': f64
|
|
|
|
79..80 'a': f64
|
|
|
|
85..111 '{ ... }': ()
|
|
|
|
99..100 'a': f64
|
|
|
|
121..127 '[b, c]': [f64; _]
|
|
|
|
122..123 'b': f64
|
|
|
|
125..126 'c': f64
|
|
|
|
131..172 '{ ... }': ()
|
|
|
|
145..146 'b': f64
|
|
|
|
160..161 'c': f64
|
2020-03-01 22:02:32 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_adt_pattern() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
enum E {
|
|
|
|
A { x: usize },
|
|
|
|
B
|
|
|
|
}
|
|
|
|
|
|
|
|
struct S(u32, E);
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let e = E::A { x: 3 };
|
|
|
|
|
|
|
|
let S(y, z) = foo;
|
|
|
|
let E::A { x: new_var } = e;
|
|
|
|
|
|
|
|
match e {
|
|
|
|
E::A { x } => x,
|
|
|
|
E::B if foo => 1,
|
|
|
|
E::B => 10,
|
|
|
|
};
|
|
|
|
|
|
|
|
let ref d @ E::A { .. } = e;
|
|
|
|
d;
|
|
|
|
}
|
|
|
|
"#),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
68..289 '{ ... d; }': ()
|
|
|
|
78..79 'e': E
|
|
|
|
82..95 'E::A { x: 3 }': E
|
|
|
|
92..93 '3': usize
|
|
|
|
106..113 'S(y, z)': S
|
|
|
|
108..109 'y': u32
|
|
|
|
111..112 'z': E
|
|
|
|
116..119 'foo': S
|
|
|
|
129..148 'E::A {..._var }': E
|
|
|
|
139..146 'new_var': usize
|
|
|
|
151..152 'e': E
|
|
|
|
159..245 'match ... }': usize
|
|
|
|
165..166 'e': E
|
|
|
|
177..187 'E::A { x }': E
|
|
|
|
184..185 'x': usize
|
|
|
|
191..192 'x': usize
|
|
|
|
202..206 'E::B': E
|
|
|
|
210..213 'foo': bool
|
|
|
|
217..218 '1': usize
|
|
|
|
228..232 'E::B': E
|
|
|
|
236..238 '10': usize
|
|
|
|
256..275 'ref d ...{ .. }': &E
|
|
|
|
264..275 'E::A { .. }': E
|
|
|
|
278..279 'e': E
|
|
|
|
285..286 'd': &E
|
2019-12-03 12:38:54 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-05-15 15:15:40 +00:00
|
|
|
#[test]
|
|
|
|
fn enum_variant_through_self_in_pattern() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
enum E {
|
|
|
|
A { x: usize },
|
|
|
|
B(usize),
|
|
|
|
C
|
|
|
|
}
|
|
|
|
|
|
|
|
impl E {
|
|
|
|
fn test() {
|
|
|
|
match (loop {}) {
|
|
|
|
Self::A { x } => { x; },
|
|
|
|
Self::B(x) => { x; },
|
|
|
|
Self::C => {},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#),
|
|
|
|
@r###"
|
|
|
|
76..218 '{ ... }': ()
|
|
|
|
86..211 'match ... }': ()
|
|
|
|
93..100 'loop {}': !
|
|
|
|
98..100 '{}': ()
|
|
|
|
116..129 'Self::A { x }': E
|
|
|
|
126..127 'x': usize
|
|
|
|
133..139 '{ x; }': ()
|
|
|
|
135..136 'x': usize
|
|
|
|
153..163 'Self::B(x)': E
|
|
|
|
161..162 'x': usize
|
|
|
|
167..173 '{ x; }': ()
|
|
|
|
169..170 'x': usize
|
|
|
|
187..194 'Self::C': E
|
|
|
|
198..200 '{}': ()
|
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_generics_in_patterns() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
struct A<T> {
|
|
|
|
x: T,
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Option<T> {
|
|
|
|
Some(T),
|
|
|
|
None,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test(a1: A<u32>, o: Option<u64>) {
|
|
|
|
let A { x: x2 } = a1;
|
|
|
|
let A::<i64> { x: x3 } = A { x: 1 };
|
|
|
|
match o {
|
|
|
|
Option::Some(t) => t,
|
|
|
|
_ => 1,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
"#),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
79..81 'a1': A<u32>
|
|
|
|
91..92 'o': Option<u64>
|
|
|
|
107..244 '{ ... }; }': ()
|
|
|
|
117..128 'A { x: x2 }': A<u32>
|
|
|
|
124..126 'x2': u32
|
|
|
|
131..133 'a1': A<u32>
|
|
|
|
143..161 'A::<i6...: x3 }': A<i64>
|
|
|
|
157..159 'x3': i64
|
|
|
|
164..174 'A { x: 1 }': A<i64>
|
|
|
|
171..172 '1': i64
|
|
|
|
180..241 'match ... }': u64
|
|
|
|
186..187 'o': Option<u64>
|
|
|
|
198..213 'Option::Some(t)': Option<u64>
|
|
|
|
211..212 't': u64
|
|
|
|
217..218 't': u64
|
|
|
|
228..229 '_': Option<u64>
|
|
|
|
233..234 '1': u64
|
2019-12-03 12:38:54 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
2020-02-21 15:56:34 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_const_pattern() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer_with_mismatches(r#"
|
|
|
|
enum Option<T> { None }
|
|
|
|
use Option::None;
|
|
|
|
struct Foo;
|
|
|
|
const Bar: usize = 1;
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let a: Option<u32> = None;
|
|
|
|
let b: Option<i64> = match a {
|
|
|
|
None => None,
|
|
|
|
};
|
|
|
|
let _: () = match () { Foo => Foo }; // Expected mismatch
|
|
|
|
let _: () = match () { Bar => Bar }; // Expected mismatch
|
|
|
|
}
|
|
|
|
"#, true),
|
|
|
|
@r###"
|
2020-04-24 21:51:02 +00:00
|
|
|
74..75 '1': usize
|
|
|
|
88..310 '{ ...atch }': ()
|
|
|
|
98..99 'a': Option<u32>
|
|
|
|
115..119 'None': Option<u32>
|
|
|
|
129..130 'b': Option<i64>
|
|
|
|
146..183 'match ... }': Option<i64>
|
|
|
|
152..153 'a': Option<u32>
|
|
|
|
164..168 'None': Option<u32>
|
|
|
|
172..176 'None': Option<i64>
|
|
|
|
193..194 '_': ()
|
|
|
|
201..224 'match ... Foo }': Foo
|
|
|
|
207..209 '()': ()
|
|
|
|
212..215 'Foo': Foo
|
|
|
|
219..222 'Foo': Foo
|
|
|
|
255..256 '_': ()
|
|
|
|
263..286 'match ... Bar }': usize
|
|
|
|
269..271 '()': ()
|
|
|
|
274..277 'Bar': usize
|
|
|
|
281..284 'Bar': usize
|
|
|
|
201..224: expected (), got Foo
|
|
|
|
263..286: expected (), got usize
|
2020-02-21 15:56:34 +00:00
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
2020-04-18 20:16:04 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_guard() {
|
|
|
|
assert_snapshot!(
|
|
|
|
infer(r#"
|
|
|
|
struct S;
|
|
|
|
impl S { fn foo(&self) -> bool { false } }
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
match S {
|
|
|
|
s if s.foo() => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#), @"
|
2020-04-24 21:51:02 +00:00
|
|
|
28..32 'self': &S
|
|
|
|
42..51 '{ false }': bool
|
|
|
|
44..49 'false': bool
|
|
|
|
65..116 '{ ... } }': ()
|
|
|
|
71..114 'match ... }': ()
|
|
|
|
77..78 'S': S
|
|
|
|
89..90 's': S
|
|
|
|
94..95 's': S
|
|
|
|
94..101 's.foo()': bool
|
|
|
|
105..107 '()': ()
|
2020-04-18 20:16:04 +00:00
|
|
|
")
|
|
|
|
}
|