diff options
author | Florian Diebold <[email protected]> | 2020-04-01 19:27:47 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-04-01 19:27:47 +0100 |
commit | b392a732d31f9be028e4b2dcf4752c5e4c7a9880 (patch) | |
tree | 5f5f3b6ea3cc70da90cf716063388ac62230f02a /crates/ra_hir_ty/src | |
parent | 0a41412ced3784363580ddaef089605250d6398e (diff) |
Add inference for literal and range patterns
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r-- | crates/ra_hir_ty/src/infer/pat.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/patterns.rs | 85 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/simple.rs | 2 |
5 files changed, 104 insertions, 3 deletions
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index baed6225b..86acd27f8 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs | |||
@@ -11,7 +11,7 @@ use hir_def::{ | |||
11 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
12 | use test_utils::tested_by; | 12 | use test_utils::tested_by; |
13 | 13 | ||
14 | use super::{BindingMode, InferenceContext}; | 14 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{utils::variant_data, Substs, Ty, TypeCtor}; | 15 | use crate::{utils::variant_data, Substs, Ty, TypeCtor}; |
16 | 16 | ||
17 | impl<'a> InferenceContext<'a> { | 17 | impl<'a> InferenceContext<'a> { |
@@ -198,7 +198,14 @@ impl<'a> InferenceContext<'a> { | |||
198 | 198 | ||
199 | Ty::apply_one(container_ty, elem_ty) | 199 | Ty::apply_one(container_ty, elem_ty) |
200 | } | 200 | } |
201 | _ => Ty::Unknown, | 201 | Pat::Wild => expected.clone(), |
202 | Pat::Range { start, end } => { | ||
203 | let start_ty = self.infer_expr(*start, &Expectation::has_type(expected.clone())); | ||
204 | let end_ty = self.infer_expr(*end, &Expectation::has_type(start_ty)); | ||
205 | end_ty | ||
206 | } | ||
207 | Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), | ||
208 | Pat::Missing => Ty::Unknown, | ||
202 | }; | 209 | }; |
203 | // use a new type variable if we got Ty::Unknown here | 210 | // use a new type variable if we got Ty::Unknown here |
204 | let ty = self.insert_type_vars_shallow(ty); | 211 | let ty = self.insert_type_vars_shallow(ty); |
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 1e303f5ce..3e3d55c04 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
@@ -275,12 +275,14 @@ fn test(i: i32) { | |||
275 | [70; 147) 'match ... }': &[i32] | 275 | [70; 147) 'match ... }': &[i32] |
276 | [76; 77) 'i': i32 | 276 | [76; 77) 'i': i32 |
277 | [88; 89) '2': i32 | 277 | [88; 89) '2': i32 |
278 | [88; 89) '2': i32 | ||
278 | [93; 96) 'foo': fn foo<i32>(&[i32]) -> &[i32] | 279 | [93; 96) 'foo': fn foo<i32>(&[i32]) -> &[i32] |
279 | [93; 102) 'foo(&[2])': &[i32] | 280 | [93; 102) 'foo(&[2])': &[i32] |
280 | [97; 101) '&[2]': &[i32; _] | 281 | [97; 101) '&[2]': &[i32; _] |
281 | [98; 101) '[2]': [i32; _] | 282 | [98; 101) '[2]': [i32; _] |
282 | [99; 100) '2': i32 | 283 | [99; 100) '2': i32 |
283 | [112; 113) '1': i32 | 284 | [112; 113) '1': i32 |
285 | [112; 113) '1': i32 | ||
284 | [117; 121) '&[1]': &[i32; _] | 286 | [117; 121) '&[1]': &[i32; _] |
285 | [118; 121) '[1]': [i32; _] | 287 | [118; 121) '[1]': [i32; _] |
286 | [119; 120) '1': i32 | 288 | [119; 120) '1': i32 |
@@ -316,10 +318,12 @@ fn test(i: i32) { | |||
316 | [70; 147) 'match ... }': &[i32] | 318 | [70; 147) 'match ... }': &[i32] |
317 | [76; 77) 'i': i32 | 319 | [76; 77) 'i': i32 |
318 | [88; 89) '1': i32 | 320 | [88; 89) '1': i32 |
321 | [88; 89) '1': i32 | ||
319 | [93; 97) '&[1]': &[i32; _] | 322 | [93; 97) '&[1]': &[i32; _] |
320 | [94; 97) '[1]': [i32; _] | 323 | [94; 97) '[1]': [i32; _] |
321 | [95; 96) '1': i32 | 324 | [95; 96) '1': i32 |
322 | [107; 108) '2': i32 | 325 | [107; 108) '2': i32 |
326 | [107; 108) '2': i32 | ||
323 | [112; 115) 'foo': fn foo<i32>(&[i32]) -> &[i32] | 327 | [112; 115) 'foo': fn foo<i32>(&[i32]) -> &[i32] |
324 | [112; 121) 'foo(&[2])': &[i32] | 328 | [112; 121) 'foo(&[2])': &[i32] |
325 | [116; 120) '&[2]': &[i32; _] | 329 | [116; 120) '&[2]': &[i32; _] |
@@ -357,9 +361,11 @@ fn test() { | |||
357 | [45; 142) 'match ... }': *const i32 | 361 | [45; 142) 'match ... }': *const i32 |
358 | [51; 52) '1': i32 | 362 | [51; 52) '1': i32 |
359 | [63; 64) '1': i32 | 363 | [63; 64) '1': i32 |
364 | [63; 64) '1': i32 | ||
360 | [68; 69) 't': &mut i32 | 365 | [68; 69) 't': &mut i32 |
361 | [68; 81) 't as *mut i32': *mut i32 | 366 | [68; 81) 't as *mut i32': *mut i32 |
362 | [91; 92) '2': i32 | 367 | [91; 92) '2': i32 |
368 | [91; 92) '2': i32 | ||
363 | [96; 97) 't': &mut i32 | 369 | [96; 97) 't': &mut i32 |
364 | [96; 105) 't as &i32': &i32 | 370 | [96; 105) 't as &i32': &i32 |
365 | [115; 116) '_': i32 | 371 | [115; 116) '_': i32 |
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index 76aa32024..6e5d2247c 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs | |||
@@ -82,6 +82,90 @@ fn test(x: &i32) { | |||
82 | } | 82 | } |
83 | 83 | ||
84 | #[test] | 84 | #[test] |
85 | fn infer_literal_pattern() { | ||
86 | assert_snapshot!( | ||
87 | infer_with_mismatches(r#" | ||
88 | fn any<T>() -> T { loop {} } | ||
89 | fn test(x: &i32) { | ||
90 | if let "foo" = any() {} | ||
91 | if let 1 = any() {} | ||
92 | if let 1u32 = any() {} | ||
93 | if let 1f32 = any() {} | ||
94 | if let 1.0 = any() {} | ||
95 | if let true = any() {} | ||
96 | } | ||
97 | "#, true), | ||
98 | @r###" | ||
99 | [18; 29) '{ loop {} }': T | ||
100 | [20; 27) 'loop {}': ! | ||
101 | [25; 27) '{}': () | ||
102 | [38; 39) 'x': &i32 | ||
103 | [47; 209) '{ ...) {} }': () | ||
104 | [53; 76) 'if let...y() {}': () | ||
105 | [60; 65) '"foo"': &str | ||
106 | [60; 65) '"foo"': &str | ||
107 | [68; 71) 'any': fn any<&str>() -> &str | ||
108 | [68; 73) 'any()': &str | ||
109 | [74; 76) '{}': () | ||
110 | [81; 100) 'if let...y() {}': () | ||
111 | [88; 89) '1': i32 | ||
112 | [88; 89) '1': i32 | ||
113 | [92; 95) 'any': fn any<i32>() -> i32 | ||
114 | [92; 97) 'any()': i32 | ||
115 | [98; 100) '{}': () | ||
116 | [105; 127) 'if let...y() {}': () | ||
117 | [112; 116) '1u32': u32 | ||
118 | [112; 116) '1u32': u32 | ||
119 | [119; 122) 'any': fn any<u32>() -> u32 | ||
120 | [119; 124) 'any()': u32 | ||
121 | [125; 127) '{}': () | ||
122 | [132; 154) 'if let...y() {}': () | ||
123 | [139; 143) '1f32': f32 | ||
124 | [139; 143) '1f32': f32 | ||
125 | [146; 149) 'any': fn any<f32>() -> f32 | ||
126 | [146; 151) 'any()': f32 | ||
127 | [152; 154) '{}': () | ||
128 | [159; 180) 'if let...y() {}': () | ||
129 | [166; 169) '1.0': f64 | ||
130 | [166; 169) '1.0': f64 | ||
131 | [172; 175) 'any': fn any<f64>() -> f64 | ||
132 | [172; 177) 'any()': f64 | ||
133 | [178; 180) '{}': () | ||
134 | [185; 207) 'if let...y() {}': () | ||
135 | [192; 196) 'true': bool | ||
136 | [192; 196) 'true': bool | ||
137 | [199; 202) 'any': fn any<bool>() -> bool | ||
138 | [199; 204) 'any()': bool | ||
139 | [205; 207) '{}': () | ||
140 | "### | ||
141 | ); | ||
142 | } | ||
143 | |||
144 | #[test] | ||
145 | fn infer_range_pattern() { | ||
146 | assert_snapshot!( | ||
147 | infer_with_mismatches(r#" | ||
148 | fn test(x: &i32) { | ||
149 | if let 1..76 = 2u32 {} | ||
150 | if let 1..=76 = 2u32 {} | ||
151 | } | ||
152 | "#, true), | ||
153 | @r###" | ||
154 | [9; 10) 'x': &i32 | ||
155 | [18; 76) '{ ...2 {} }': () | ||
156 | [24; 46) 'if let...u32 {}': () | ||
157 | [31; 36) '1..76': u32 | ||
158 | [39; 43) '2u32': u32 | ||
159 | [44; 46) '{}': () | ||
160 | [51; 74) 'if let...u32 {}': () | ||
161 | [58; 64) '1..=76': u32 | ||
162 | [67; 71) '2u32': u32 | ||
163 | [72; 74) '{}': () | ||
164 | "### | ||
165 | ); | ||
166 | } | ||
167 | |||
168 | #[test] | ||
85 | fn infer_pattern_match_ergonomics() { | 169 | fn infer_pattern_match_ergonomics() { |
86 | assert_snapshot!( | 170 | assert_snapshot!( |
87 | infer(r#" | 171 | infer(r#" |
@@ -212,6 +296,7 @@ fn test() { | |||
212 | [59; 62) 'arr': [f64; _] | 296 | [59; 62) 'arr': [f64; _] |
213 | [73; 81) '[1.0, a]': [f64; _] | 297 | [73; 81) '[1.0, a]': [f64; _] |
214 | [74; 77) '1.0': f64 | 298 | [74; 77) '1.0': f64 |
299 | [74; 77) '1.0': f64 | ||
215 | [79; 80) 'a': f64 | 300 | [79; 80) 'a': f64 |
216 | [85; 111) '{ ... }': () | 301 | [85; 111) '{ ... }': () |
217 | [99; 100) 'a': f64 | 302 | [99; 100) 'a': f64 |
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index a02e3ee05..2ee9b8f10 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs | |||
@@ -206,7 +206,8 @@ pub fn compute() { | |||
206 | [24; 106) 'match ... }': () | 206 | [24; 106) 'match ... }': () |
207 | [30; 37) 'nope!()': {unknown} | 207 | [30; 37) 'nope!()': {unknown} |
208 | [48; 94) 'SizeSk...tail }': {unknown} | 208 | [48; 94) 'SizeSk...tail }': {unknown} |
209 | [82; 86) 'true': {unknown} | 209 | [82; 86) 'true': bool |
210 | [82; 86) 'true': bool | ||
210 | [88; 92) 'tail': {unknown} | 211 | [88; 92) 'tail': {unknown} |
211 | [98; 100) '{}': () | 212 | [98; 100) '{}': () |
212 | "### | 213 | "### |
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index c140bd513..a600b947d 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs | |||
@@ -948,6 +948,7 @@ fn foo() { | |||
948 | [165; 247) 'match ... }': i32 | 948 | [165; 247) 'match ... }': i32 |
949 | [171; 175) 'true': bool | 949 | [171; 175) 'true': bool |
950 | [186; 190) 'true': bool | 950 | [186; 190) 'true': bool |
951 | [186; 190) 'true': bool | ||
951 | [194; 195) '3': i32 | 952 | [194; 195) '3': i32 |
952 | [205; 206) '_': bool | 953 | [205; 206) '_': bool |
953 | [210; 241) '{ ... }': ! | 954 | [210; 241) '{ ... }': ! |
@@ -956,6 +957,7 @@ fn foo() { | |||
956 | [263; 320) 'match ... }': i32 | 957 | [263; 320) 'match ... }': i32 |
957 | [269; 273) 'true': bool | 958 | [269; 273) 'true': bool |
958 | [284; 288) 'true': bool | 959 | [284; 288) 'true': bool |
960 | [284; 288) 'true': bool | ||
959 | [292; 293) '4': i32 | 961 | [292; 293) '4': i32 |
960 | [303; 304) '_': bool | 962 | [303; 304) '_': bool |
961 | [308; 314) 'return': ! | 963 | [308; 314) 'return': ! |