diff options
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/src/display.rs | 44 | ||||
-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 |
6 files changed, 121 insertions, 30 deletions
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs index a6ef44a31..13ecd537a 100644 --- a/crates/ra_hir_ty/src/display.rs +++ b/crates/ra_hir_ty/src/display.rs | |||
@@ -159,20 +159,13 @@ impl HirDisplay for ApplicationTy { | |||
159 | } | 159 | } |
160 | TypeCtor::FnDef(def) => { | 160 | TypeCtor::FnDef(def) => { |
161 | let sig = f.db.callable_item_signature(def).subst(&self.parameters); | 161 | let sig = f.db.callable_item_signature(def).subst(&self.parameters); |
162 | let name = match def { | 162 | match def { |
163 | CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), | 163 | CallableDef::FunctionId(ff) => write!(f, "fn {}", f.db.function_data(ff).name)?, |
164 | CallableDef::StructId(s) => f.db.struct_data(s).name.clone(), | 164 | CallableDef::StructId(s) => write!(f, "{}", f.db.struct_data(s).name)?, |
165 | CallableDef::EnumVariantId(e) => { | 165 | CallableDef::EnumVariantId(e) => { |
166 | let enum_data = f.db.enum_data(e.parent); | 166 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? |
167 | enum_data.variants[e.local_id].name.clone() | ||
168 | } | 167 | } |
169 | }; | 168 | }; |
170 | match def { | ||
171 | CallableDef::FunctionId(_) => write!(f, "fn {}", name)?, | ||
172 | CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { | ||
173 | write!(f, "{}", name)? | ||
174 | } | ||
175 | } | ||
176 | if self.parameters.len() > 0 { | 169 | if self.parameters.len() > 0 { |
177 | let generics = generics(f.db.upcast(), def.into()); | 170 | let generics = generics(f.db.upcast(), def.into()); |
178 | let (parent_params, self_param, type_params, _impl_trait_params) = | 171 | let (parent_params, self_param, type_params, _impl_trait_params) = |
@@ -197,8 +190,6 @@ impl HirDisplay for ApplicationTy { | |||
197 | }; | 190 | }; |
198 | write!(f, "{}", name)?; | 191 | write!(f, "{}", name)?; |
199 | if self.parameters.len() > 0 { | 192 | if self.parameters.len() > 0 { |
200 | write!(f, "<")?; | ||
201 | |||
202 | let mut non_default_parameters = Vec::with_capacity(self.parameters.len()); | 193 | let mut non_default_parameters = Vec::with_capacity(self.parameters.len()); |
203 | let parameters_to_write = if f.omit_verbose_types() { | 194 | let parameters_to_write = if f.omit_verbose_types() { |
204 | match self | 195 | match self |
@@ -207,8 +198,8 @@ impl HirDisplay for ApplicationTy { | |||
207 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 198 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
208 | .filter(|defaults| !defaults.is_empty()) | 199 | .filter(|defaults| !defaults.is_empty()) |
209 | { | 200 | { |
210 | Option::None => self.parameters.0.as_ref(), | 201 | None => self.parameters.0.as_ref(), |
211 | Option::Some(default_parameters) => { | 202 | Some(default_parameters) => { |
212 | for (i, parameter) in self.parameters.iter().enumerate() { | 203 | for (i, parameter) in self.parameters.iter().enumerate() { |
213 | match (parameter, default_parameters.get(i)) { | 204 | match (parameter, default_parameters.get(i)) { |
214 | (&Ty::Unknown, _) | (_, None) => { | 205 | (&Ty::Unknown, _) | (_, None) => { |
@@ -228,7 +219,7 @@ impl HirDisplay for ApplicationTy { | |||
228 | } else { | 219 | } else { |
229 | self.parameters.0.as_ref() | 220 | self.parameters.0.as_ref() |
230 | }; | 221 | }; |
231 | 222 | write!(f, "<")?; | |
232 | f.write_joined(parameters_to_write, ", ")?; | 223 | f.write_joined(parameters_to_write, ", ")?; |
233 | write!(f, ">")?; | 224 | write!(f, ">")?; |
234 | } | 225 | } |
@@ -238,9 +229,9 @@ impl HirDisplay for ApplicationTy { | |||
238 | AssocContainerId::TraitId(it) => it, | 229 | AssocContainerId::TraitId(it) => it, |
239 | _ => panic!("not an associated type"), | 230 | _ => panic!("not an associated type"), |
240 | }; | 231 | }; |
241 | let trait_name = f.db.trait_data(trait_).name.clone(); | 232 | let trait_ = f.db.trait_data(trait_); |
242 | let name = f.db.type_alias_data(type_alias).name.clone(); | 233 | let type_alias = f.db.type_alias_data(type_alias); |
243 | write!(f, "{}::{}", trait_name, name)?; | 234 | write!(f, "{}::{}", trait_.name, type_alias.name)?; |
244 | if self.parameters.len() > 0 { | 235 | if self.parameters.len() > 0 { |
245 | write!(f, "<")?; | 236 | write!(f, "<")?; |
246 | f.write_joined(&*self.parameters.0, ", ")?; | 237 | f.write_joined(&*self.parameters.0, ", ")?; |
@@ -273,8 +264,8 @@ impl HirDisplay for ProjectionTy { | |||
273 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 264 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
274 | } | 265 | } |
275 | 266 | ||
276 | let trait_name = f.db.trait_data(self.trait_(f.db)).name.clone(); | 267 | let trait_ = f.db.trait_data(self.trait_(f.db)); |
277 | write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; | 268 | write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_.name)?; |
278 | if self.parameters.len() > 1 { | 269 | if self.parameters.len() > 1 { |
279 | write!(f, "<")?; | 270 | write!(f, "<")?; |
280 | f.write_joined(&self.parameters[1..], ", ")?; | 271 | f.write_joined(&self.parameters[1..], ", ")?; |
@@ -319,7 +310,7 @@ impl HirDisplay for Ty { | |||
319 | Ty::Opaque(_) => write!(f, "impl ")?, | 310 | Ty::Opaque(_) => write!(f, "impl ")?, |
320 | _ => unreachable!(), | 311 | _ => unreachable!(), |
321 | }; | 312 | }; |
322 | write_bounds_like_dyn_trait(&predicates, f)?; | 313 | write_bounds_like_dyn_trait(predicates, f)?; |
323 | } | 314 | } |
324 | Ty::Unknown => write!(f, "{{unknown}}")?, | 315 | Ty::Unknown => write!(f, "{{unknown}}")?, |
325 | Ty::Infer(..) => write!(f, "_")?, | 316 | Ty::Infer(..) => write!(f, "_")?, |
@@ -352,7 +343,7 @@ fn write_bounds_like_dyn_trait( | |||
352 | // We assume that the self type is $0 (i.e. the | 343 | // We assume that the self type is $0 (i.e. the |
353 | // existential) here, which is the only thing that's | 344 | // existential) here, which is the only thing that's |
354 | // possible in actual Rust, and hence don't print it | 345 | // possible in actual Rust, and hence don't print it |
355 | write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?; | 346 | write!(f, "{}", f.db.trait_data(trait_ref.trait_).name)?; |
356 | if trait_ref.substs.len() > 1 { | 347 | if trait_ref.substs.len() > 1 { |
357 | write!(f, "<")?; | 348 | write!(f, "<")?; |
358 | f.write_joined(&trait_ref.substs[1..], ", ")?; | 349 | f.write_joined(&trait_ref.substs[1..], ", ")?; |
@@ -369,9 +360,8 @@ fn write_bounds_like_dyn_trait( | |||
369 | write!(f, "<")?; | 360 | write!(f, "<")?; |
370 | angle_open = true; | 361 | angle_open = true; |
371 | } | 362 | } |
372 | let name = | 363 | let type_alias = f.db.type_alias_data(projection_pred.projection_ty.associated_ty); |
373 | f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name.clone(); | 364 | write!(f, "{} = ", type_alias.name)?; |
374 | write!(f, "{} = ", name)?; | ||
375 | projection_pred.ty.hir_fmt(f)?; | 365 | projection_pred.ty.hir_fmt(f)?; |
376 | } | 366 | } |
377 | GenericPredicate::Error => { | 367 | GenericPredicate::Error => { |
@@ -405,7 +395,7 @@ impl TraitRef { | |||
405 | } else { | 395 | } else { |
406 | write!(f, ": ")?; | 396 | write!(f, ": ")?; |
407 | } | 397 | } |
408 | write!(f, "{}", f.db.trait_data(self.trait_).name.clone())?; | 398 | write!(f, "{}", f.db.trait_data(self.trait_).name)?; |
409 | if self.substs.len() > 1 { | 399 | if self.substs.len() > 1 { |
410 | write!(f, "<")?; | 400 | write!(f, "<")?; |
411 | f.write_joined(&self.substs[1..], ", ")?; | 401 | f.write_joined(&self.substs[1..], ", ")?; |
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': ! |