diff options
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 162 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap | 46 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap | 26 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 23 |
9 files changed, 227 insertions, 84 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 191104890..e4008058c 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -424,6 +424,10 @@ impl Function { | |||
424 | self.id.module(db) | 424 | self.id.module(db) |
425 | } | 425 | } |
426 | 426 | ||
427 | pub fn name(&self, db: &impl HirDatabase) -> Name { | ||
428 | self.signature(db).name.clone() | ||
429 | } | ||
430 | |||
427 | pub fn body_syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> { | 431 | pub fn body_syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> { |
428 | db.body_syntax_mapping(*self) | 432 | db.body_syntax_mapping(*self) |
429 | } | 433 | } |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 31ea45706..37715a903 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -20,6 +20,7 @@ mod tests; | |||
20 | pub(crate) mod method_resolution; | 20 | pub(crate) mod method_resolution; |
21 | 21 | ||
22 | use std::borrow::Cow; | 22 | use std::borrow::Cow; |
23 | use std::iter::repeat; | ||
23 | use std::ops::Index; | 24 | use std::ops::Index; |
24 | use std::sync::Arc; | 25 | use std::sync::Arc; |
25 | use std::{fmt, mem}; | 26 | use std::{fmt, mem}; |
@@ -185,7 +186,7 @@ pub enum Ty { | |||
185 | 186 | ||
186 | /// Structures, enumerations and unions. | 187 | /// Structures, enumerations and unions. |
187 | Adt { | 188 | Adt { |
188 | /// The DefId of the struct/enum. | 189 | /// The definition of the struct/enum. |
189 | def_id: AdtDef, | 190 | def_id: AdtDef, |
190 | /// The name, for displaying. | 191 | /// The name, for displaying. |
191 | name: Name, | 192 | name: Name, |
@@ -209,6 +210,27 @@ pub enum Ty { | |||
209 | /// `&'a mut T` or `&'a T`. | 210 | /// `&'a mut T` or `&'a T`. |
210 | Ref(Arc<Ty>, Mutability), | 211 | Ref(Arc<Ty>, Mutability), |
211 | 212 | ||
213 | /// The anonymous type of a function declaration/definition. Each | ||
214 | /// function has a unique type, which is output (for a function | ||
215 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
216 | /// | ||
217 | /// For example the type of `bar` here: | ||
218 | /// | ||
219 | /// ```rust | ||
220 | /// fn foo() -> i32 { 1 } | ||
221 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
222 | /// ``` | ||
223 | FnDef { | ||
224 | // Function definition | ||
225 | def: Function, | ||
226 | /// For display | ||
227 | name: Name, | ||
228 | /// Parameters and return type | ||
229 | sig: Arc<FnSig>, | ||
230 | /// Substitutions for the generic parameters of the type | ||
231 | substs: Substs, | ||
232 | }, | ||
233 | |||
212 | /// A pointer to a function. Written as `fn() -> i32`. | 234 | /// A pointer to a function. Written as `fn() -> i32`. |
213 | /// | 235 | /// |
214 | /// For example the type of `bar` here: | 236 | /// For example the type of `bar` here: |
@@ -448,12 +470,12 @@ impl Ty { | |||
448 | } | 470 | } |
449 | // add placeholders for args that were not provided | 471 | // add placeholders for args that were not provided |
450 | // TODO: handle defaults | 472 | // TODO: handle defaults |
451 | for _ in segment | 473 | let supplied_params = segment |
452 | .args_and_bindings | 474 | .args_and_bindings |
453 | .as_ref() | 475 | .as_ref() |
454 | .map(|ga| ga.args.len()) | 476 | .map(|ga| ga.args.len()) |
455 | .unwrap_or(0)..def_generics.params.len() | 477 | .unwrap_or(0); |
456 | { | 478 | for _ in supplied_params..def_generics.params.len() { |
457 | substs.push(Ty::Unknown); | 479 | substs.push(Ty::Unknown); |
458 | } | 480 | } |
459 | assert_eq!(substs.len(), def_generics.params.len()); | 481 | assert_eq!(substs.len(), def_generics.params.len()); |
@@ -485,6 +507,19 @@ impl Ty { | |||
485 | } | 507 | } |
486 | sig_mut.output.walk_mut(f); | 508 | sig_mut.output.walk_mut(f); |
487 | } | 509 | } |
510 | Ty::FnDef { substs, sig, .. } => { | ||
511 | let sig_mut = Arc::make_mut(sig); | ||
512 | for input in &mut sig_mut.input { | ||
513 | input.walk_mut(f); | ||
514 | } | ||
515 | sig_mut.output.walk_mut(f); | ||
516 | // Without an Arc::make_mut_slice, we can't avoid the clone here: | ||
517 | let mut v: Vec<_> = substs.0.iter().cloned().collect(); | ||
518 | for t in &mut v { | ||
519 | t.walk_mut(f); | ||
520 | } | ||
521 | substs.0 = v.into(); | ||
522 | } | ||
488 | Ty::Adt { substs, .. } => { | 523 | Ty::Adt { substs, .. } => { |
489 | // Without an Arc::make_mut_slice, we can't avoid the clone here: | 524 | // Without an Arc::make_mut_slice, we can't avoid the clone here: |
490 | let mut v: Vec<_> = substs.0.iter().cloned().collect(); | 525 | let mut v: Vec<_> = substs.0.iter().cloned().collect(); |
@@ -524,6 +559,12 @@ impl Ty { | |||
524 | name, | 559 | name, |
525 | substs, | 560 | substs, |
526 | }, | 561 | }, |
562 | Ty::FnDef { def, name, sig, .. } => Ty::FnDef { | ||
563 | def, | ||
564 | name, | ||
565 | sig, | ||
566 | substs, | ||
567 | }, | ||
527 | _ => self, | 568 | _ => self, |
528 | } | 569 | } |
529 | } | 570 | } |
@@ -551,7 +592,7 @@ impl Ty { | |||
551 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 592 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
552 | fn substs(&self) -> Option<Substs> { | 593 | fn substs(&self) -> Option<Substs> { |
553 | match self { | 594 | match self { |
554 | Ty::Adt { substs, .. } => Some(substs.clone()), | 595 | Ty::Adt { substs, .. } | Ty::FnDef { substs, .. } => Some(substs.clone()), |
555 | _ => None, | 596 | _ => None, |
556 | } | 597 | } |
557 | } | 598 | } |
@@ -586,6 +627,22 @@ impl fmt::Display for Ty { | |||
586 | .to_fmt(f)?; | 627 | .to_fmt(f)?; |
587 | write!(f, " -> {}", sig.output) | 628 | write!(f, " -> {}", sig.output) |
588 | } | 629 | } |
630 | Ty::FnDef { | ||
631 | name, substs, sig, .. | ||
632 | } => { | ||
633 | write!(f, "fn {}", name)?; | ||
634 | if substs.0.len() > 0 { | ||
635 | join(substs.0.iter()) | ||
636 | .surround_with("<", ">") | ||
637 | .separator(", ") | ||
638 | .to_fmt(f)?; | ||
639 | } | ||
640 | join(sig.input.iter()) | ||
641 | .surround_with("(", ")") | ||
642 | .separator(", ") | ||
643 | .to_fmt(f)?; | ||
644 | write!(f, " -> {}", sig.output) | ||
645 | } | ||
589 | Ty::Adt { name, substs, .. } => { | 646 | Ty::Adt { name, substs, .. } => { |
590 | write!(f, "{}", name)?; | 647 | write!(f, "{}", name)?; |
591 | if substs.0.len() > 0 { | 648 | if substs.0.len() > 0 { |
@@ -607,11 +664,11 @@ impl fmt::Display for Ty { | |||
607 | 664 | ||
608 | /// Compute the declared type of a function. This should not need to look at the | 665 | /// Compute the declared type of a function. This should not need to look at the |
609 | /// function body. | 666 | /// function body. |
610 | fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { | 667 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { |
611 | let signature = f.signature(db); | 668 | let signature = def.signature(db); |
612 | let module = f.module(db); | 669 | let module = def.module(db); |
613 | let impl_block = f.impl_block(db); | 670 | let impl_block = def.impl_block(db); |
614 | let generics = f.generic_params(db); | 671 | let generics = def.generic_params(db); |
615 | let input = signature | 672 | let input = signature |
616 | .params() | 673 | .params() |
617 | .iter() | 674 | .iter() |
@@ -624,8 +681,15 @@ fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { | |||
624 | &generics, | 681 | &generics, |
625 | signature.ret_type(), | 682 | signature.ret_type(), |
626 | ); | 683 | ); |
627 | let sig = FnSig { input, output }; | 684 | let sig = Arc::new(FnSig { input, output }); |
628 | Ty::FnPtr(Arc::new(sig)) | 685 | let substs = make_substs(&generics); |
686 | let name = def.name(db); | ||
687 | Ty::FnDef { | ||
688 | def, | ||
689 | sig, | ||
690 | name, | ||
691 | substs, | ||
692 | } | ||
629 | } | 693 | } |
630 | 694 | ||
631 | fn make_substs(generics: &GenericParams) -> Substs { | 695 | fn make_substs(generics: &GenericParams) -> Substs { |
@@ -1102,7 +1166,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1102 | .into(); | 1166 | .into(); |
1103 | let typable = typable?; | 1167 | let typable = typable?; |
1104 | let ty = self.db.type_for_def(typable); | 1168 | let ty = self.db.type_for_def(typable); |
1169 | let generics = GenericParams::default(); | ||
1170 | let substs = Ty::substs_from_path( | ||
1171 | self.db, | ||
1172 | &self.module, | ||
1173 | self.impl_block.as_ref(), | ||
1174 | &generics, | ||
1175 | path, | ||
1176 | typable, | ||
1177 | ); | ||
1178 | let ty = ty.apply_substs(substs); | ||
1105 | let ty = self.insert_type_vars(ty); | 1179 | let ty = self.insert_type_vars(ty); |
1180 | |||
1106 | Some(ty) | 1181 | Some(ty) |
1107 | } | 1182 | } |
1108 | 1183 | ||
@@ -1142,7 +1217,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1142 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 1217 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
1143 | (ty, Some(var.into())) | 1218 | (ty, Some(var.into())) |
1144 | } | 1219 | } |
1145 | TypableDef::Enum(_) | TypableDef::Function(_) => (Ty::Unknown, None), | 1220 | TypableDef::Function(_) | TypableDef::Enum(_) => (Ty::Unknown, None), |
1146 | } | 1221 | } |
1147 | } | 1222 | } |
1148 | 1223 | ||
@@ -1196,9 +1271,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1196 | Ty::Tuple(ref tuple_args) => &**tuple_args, | 1271 | Ty::Tuple(ref tuple_args) => &**tuple_args, |
1197 | _ => &[], | 1272 | _ => &[], |
1198 | }; | 1273 | }; |
1199 | let expectations_iter = expectations | 1274 | let expectations_iter = expectations.into_iter().chain(repeat(&Ty::Unknown)); |
1200 | .into_iter() | ||
1201 | .chain(std::iter::repeat(&Ty::Unknown)); | ||
1202 | 1275 | ||
1203 | let inner_tys = args | 1276 | let inner_tys = args |
1204 | .iter() | 1277 | .iter() |
@@ -1332,18 +1405,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1332 | Expr::Call { callee, args } => { | 1405 | Expr::Call { callee, args } => { |
1333 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); | 1406 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); |
1334 | let (param_tys, ret_ty) = match &callee_ty { | 1407 | let (param_tys, ret_ty) = match &callee_ty { |
1335 | Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), | 1408 | Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), |
1409 | Ty::FnDef { substs, sig, .. } => { | ||
1410 | let ret_ty = sig.output.clone().subst(&substs); | ||
1411 | let param_tys = sig | ||
1412 | .input | ||
1413 | .iter() | ||
1414 | .map(|ty| ty.clone().subst(&substs)) | ||
1415 | .collect(); | ||
1416 | (param_tys, ret_ty) | ||
1417 | } | ||
1336 | _ => { | 1418 | _ => { |
1337 | // not callable | 1419 | // not callable |
1338 | // TODO report an error? | 1420 | // TODO report an error? |
1339 | (&[][..], Ty::Unknown) | 1421 | (Vec::new(), Ty::Unknown) |
1340 | } | 1422 | } |
1341 | }; | 1423 | }; |
1342 | for (i, arg) in args.iter().enumerate() { | 1424 | let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); |
1343 | self.infer_expr( | 1425 | for (arg, param) in args.iter().zip(param_iter) { |
1344 | *arg, | 1426 | self.infer_expr(*arg, &Expectation::has_type(param)); |
1345 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | ||
1346 | ); | ||
1347 | } | 1427 | } |
1348 | ret_ty | 1428 | ret_ty |
1349 | } | 1429 | } |
@@ -1365,21 +1445,34 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1365 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { | 1445 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { |
1366 | Ty::FnPtr(sig) => { | 1446 | Ty::FnPtr(sig) => { |
1367 | if sig.input.len() > 0 { | 1447 | if sig.input.len() > 0 { |
1368 | (&sig.input[0], &sig.input[1..], sig.output.clone()) | 1448 | ( |
1449 | sig.input[0].clone(), | ||
1450 | sig.input[1..].iter().cloned().collect(), | ||
1451 | sig.output.clone(), | ||
1452 | ) | ||
1369 | } else { | 1453 | } else { |
1370 | (&Ty::Unknown, &[][..], sig.output.clone()) | 1454 | (Ty::Unknown, Vec::new(), sig.output.clone()) |
1371 | } | 1455 | } |
1372 | } | 1456 | } |
1373 | _ => (&Ty::Unknown, &[][..], Ty::Unknown), | 1457 | Ty::FnDef { substs, sig, .. } => { |
1458 | let ret_ty = sig.output.clone().subst(&substs); | ||
1459 | |||
1460 | if sig.input.len() > 0 { | ||
1461 | let mut arg_iter = sig.input.iter().map(|ty| ty.clone().subst(&substs)); | ||
1462 | let receiver_ty = arg_iter.next().unwrap(); | ||
1463 | (receiver_ty, arg_iter.collect(), ret_ty) | ||
1464 | } else { | ||
1465 | (Ty::Unknown, Vec::new(), ret_ty) | ||
1466 | } | ||
1467 | } | ||
1468 | _ => (Ty::Unknown, Vec::new(), Ty::Unknown), | ||
1374 | }; | 1469 | }; |
1375 | // TODO we would have to apply the autoderef/autoref steps here | 1470 | // TODO we would have to apply the autoderef/autoref steps here |
1376 | // to get the correct receiver type to unify... | 1471 | // to get the correct receiver type to unify... |
1377 | self.unify(expected_receiver_ty, &receiver_ty); | 1472 | self.unify(&expected_receiver_ty, &receiver_ty); |
1378 | for (i, arg) in args.iter().enumerate() { | 1473 | let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); |
1379 | self.infer_expr( | 1474 | for (arg, param) in args.iter().zip(param_iter) { |
1380 | *arg, | 1475 | self.infer_expr(*arg, &Expectation::has_type(param)); |
1381 | &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), | ||
1382 | ); | ||
1383 | } | 1476 | } |
1384 | ret_ty | 1477 | ret_ty |
1385 | } | 1478 | } |
@@ -1609,10 +1702,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1609 | 1702 | ||
1610 | self.infer_pat(*pat, &ty); | 1703 | self.infer_pat(*pat, &ty); |
1611 | } | 1704 | } |
1612 | self.return_ty = { | 1705 | self.return_ty = self.make_ty(signature.ret_type()); |
1613 | let ty = self.make_ty(signature.ret_type()); | ||
1614 | ty | ||
1615 | }; | ||
1616 | } | 1706 | } |
1617 | 1707 | ||
1618 | fn infer_body(&mut self) { | 1708 | fn infer_body(&mut self) { |
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap index 5c74bd8c7..f5840a934 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap | |||
@@ -1,8 +1,8 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-22T14:44:59.880187500+00:00" | 2 | created: "2019-01-26T17:46:03.842478456+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.2 |
4 | expression: "&result" | 4 | expression: "&result" |
5 | source: "crates\\ra_hir\\src\\ty\\tests.rs" | 5 | source: crates/ra_hir/src/ty/tests.rs |
6 | --- | 6 | --- |
7 | [14; 15) 'x': u32 | 7 | [14; 15) 'x': u32 |
8 | [22; 24) '{}': () | 8 | [22; 24) '{}': () |
@@ -10,7 +10,7 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs" | |||
10 | [88; 89) 'a': u32 | 10 | [88; 89) 'a': u32 |
11 | [92; 108) 'unknow...nction': [unknown] | 11 | [92; 108) 'unknow...nction': [unknown] |
12 | [92; 110) 'unknow...tion()': u32 | 12 | [92; 110) 'unknow...tion()': u32 |
13 | [116; 125) 'takes_u32': fn(u32) -> () | 13 | [116; 125) 'takes_u32': fn takes_u32(u32) -> () |
14 | [116; 128) 'takes_u32(a)': () | 14 | [116; 128) 'takes_u32(a)': () |
15 | [126; 127) 'a': u32 | 15 | [126; 127) 'a': u32 |
16 | [138; 139) 'b': i32 | 16 | [138; 139) 'b': i32 |
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap index c506bcadd..b9dda2bc0 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap | |||
@@ -1,8 +1,8 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-22T14:44:59.880187500+00:00" | 2 | created: "2019-01-26T17:46:03.853259898+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.2 |
4 | expression: "&result" | 4 | expression: "&result" |
5 | source: "crates\\ra_hir\\src\\ty\\tests.rs" | 5 | source: crates/ra_hir/src/ty/tests.rs |
6 | --- | 6 | --- |
7 | [6; 7) 'x': bool | 7 | [6; 7) 'x': bool |
8 | [22; 34) '{ 0i32 }': i32 | 8 | [22; 34) '{ 0i32 }': i32 |
@@ -28,7 +28,7 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs" | |||
28 | [174; 196) 'minus_...ONST_2': bool | 28 | [174; 196) 'minus_...ONST_2': bool |
29 | [189; 196) 'CONST_2': isize | 29 | [189; 196) 'CONST_2': isize |
30 | [206; 207) 'c': i32 | 30 | [206; 207) 'c': i32 |
31 | [210; 211) 'f': fn(bool) -> i32 | 31 | [210; 211) 'f': fn f(bool) -> i32 |
32 | [210; 219) 'f(z || y)': i32 | 32 | [210; 219) 'f(z || y)': i32 |
33 | [210; 223) 'f(z || y) + 5': i32 | 33 | [210; 223) 'f(z || y) + 5': i32 |
34 | [212; 213) 'z': bool | 34 | [212; 213) 'z': bool |
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap index 7203ad1e2..8ff6e55a6 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap | |||
@@ -1,21 +1,21 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-22T14:44:59.954958500+00:00" | 2 | created: "2019-01-26T18:16:16.530712344+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.2 |
4 | expression: "&result" | 4 | expression: "&result" |
5 | source: "crates\\ra_hir\\src\\ty\\tests.rs" | 5 | source: crates/ra_hir/src/ty/tests.rs |
6 | --- | 6 | --- |
7 | [10; 11) 't': [unknown] | 7 | [10; 11) 't': [unknown] |
8 | [21; 26) '{ t }': [unknown] | 8 | [21; 26) '{ t }': [unknown] |
9 | [23; 24) 't': [unknown] | 9 | [23; 24) 't': [unknown] |
10 | [38; 98) '{ ...(1); }': () | 10 | [38; 98) '{ ...(1); }': () |
11 | [44; 46) 'id': fn(T) -> T | 11 | [44; 46) 'id': fn id<u32>(T) -> T |
12 | [44; 52) 'id(1u32)': T | 12 | [44; 52) 'id(1u32)': u32 |
13 | [47; 51) '1u32': u32 | 13 | [47; 51) '1u32': u32 |
14 | [58; 68) 'id::<i128>': fn(T) -> T | 14 | [58; 68) 'id::<i128>': fn id<i128>(T) -> T |
15 | [58; 71) 'id::<i128>(1)': T | 15 | [58; 71) 'id::<i128>(1)': i128 |
16 | [69; 70) '1': T | 16 | [69; 70) '1': i128 |
17 | [81; 82) 'x': T | 17 | [81; 82) 'x': u64 |
18 | [90; 92) 'id': fn(T) -> T | 18 | [90; 92) 'id': fn id<u64>(T) -> T |
19 | [90; 95) 'id(1)': T | 19 | [90; 95) 'id(1)': u64 |
20 | [93; 94) '1': T | 20 | [93; 94) '1': u64 |
21 | 21 | ||
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap index 4435180a1..f21bffa75 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap | |||
@@ -1,8 +1,8 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-22T14:44:59.961936900+00:00" | 2 | created: "2019-01-26T17:46:03.866825843+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.2 |
4 | expression: "&result" | 4 | expression: "&result" |
5 | source: "crates\\ra_hir\\src\\ty\\tests.rs" | 5 | source: crates/ra_hir/src/ty/tests.rs |
6 | --- | 6 | --- |
7 | [53; 57) 'self': A<[unknown]> | 7 | [53; 57) 'self': A<[unknown]> |
8 | [65; 87) '{ ... }': [unknown] | 8 | [65; 87) '{ ... }': [unknown] |
@@ -12,25 +12,25 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs" | |||
12 | [110; 115) '{ t }': [unknown] | 12 | [110; 115) '{ t }': [unknown] |
13 | [112; 113) 't': [unknown] | 13 | [112; 113) 't': [unknown] |
14 | [135; 261) '{ ....x() }': i128 | 14 | [135; 261) '{ ....x() }': i128 |
15 | [146; 147) 'x': T | 15 | [146; 147) 'x': i32 |
16 | [150; 151) '1': T | 16 | [150; 151) '1': i32 |
17 | [162; 163) 'y': T | 17 | [162; 163) 'y': i32 |
18 | [166; 168) 'id': fn(T) -> T | 18 | [166; 168) 'id': fn id<i32>(T) -> T |
19 | [166; 171) 'id(x)': T | 19 | [166; 171) 'id(x)': i32 |
20 | [169; 170) 'x': T | 20 | [169; 170) 'x': i32 |
21 | [182; 183) 'a': A<T> | 21 | [182; 183) 'a': A<i32> |
22 | [186; 200) 'A { x: id(y) }': A<T> | 22 | [186; 200) 'A { x: id(y) }': A<i32> |
23 | [193; 195) 'id': fn(T) -> T | 23 | [193; 195) 'id': fn id<i32>(T) -> T |
24 | [193; 198) 'id(y)': T | 24 | [193; 198) 'id(y)': i32 |
25 | [196; 197) 'y': T | 25 | [196; 197) 'y': i32 |
26 | [211; 212) 'z': T | 26 | [211; 212) 'z': i32 |
27 | [215; 217) 'id': fn(T) -> T | 27 | [215; 217) 'id': fn id<i32>(T) -> T |
28 | [215; 222) 'id(a.x)': T | 28 | [215; 222) 'id(a.x)': i32 |
29 | [218; 219) 'a': A<T> | 29 | [218; 219) 'a': A<i32> |
30 | [218; 221) 'a.x': T | 30 | [218; 221) 'a.x': i32 |
31 | [233; 234) 'b': A<T> | 31 | [233; 234) 'b': A<i32> |
32 | [237; 247) 'A { x: z }': A<T> | 32 | [237; 247) 'A { x: z }': A<i32> |
33 | [244; 245) 'z': T | 33 | [244; 245) 'z': i32 |
34 | [254; 255) 'b': A<T> | 34 | [254; 255) 'b': A<i32> |
35 | [254; 259) 'b.x()': i128 | 35 | [254; 259) 'b.x()': i128 |
36 | 36 | ||
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap index 0bceffaef..afbe2f747 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap | |||
@@ -1,16 +1,16 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-22T14:44:59.975899500+00:00" | 2 | created: "2019-01-26T17:46:03.928773630+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.2 |
4 | expression: "&result" | 4 | expression: "&result" |
5 | source: "crates\\ra_hir\\src\\ty\\tests.rs" | 5 | source: crates/ra_hir/src/ty/tests.rs |
6 | --- | 6 | --- |
7 | [15; 20) '{ 1 }': u32 | 7 | [15; 20) '{ 1 }': u32 |
8 | [17; 18) '1': u32 | 8 | [17; 18) '1': u32 |
9 | [48; 53) '{ 1 }': u32 | 9 | [48; 53) '{ 1 }': u32 |
10 | [50; 51) '1': u32 | 10 | [50; 51) '1': u32 |
11 | [67; 91) '{ ...c(); }': () | 11 | [67; 91) '{ ...c(); }': () |
12 | [73; 74) 'a': fn() -> u32 | 12 | [73; 74) 'a': fn a() -> u32 |
13 | [73; 76) 'a()': u32 | 13 | [73; 76) 'a()': u32 |
14 | [82; 86) 'b::c': fn() -> u32 | 14 | [82; 86) 'b::c': fn c() -> u32 |
15 | [82; 88) 'b::c()': u32 | 15 | [82; 88) 'b::c()': u32 |
16 | 16 | ||
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap new file mode 100644 index 000000000..a99323264 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap | |||
@@ -0,0 +1,26 @@ | |||
1 | --- | ||
2 | created: "2019-01-27T16:54:18.368427685+00:00" | ||
3 | creator: [email protected] | ||
4 | expression: "&result" | ||
5 | source: crates/ra_hir/src/ty/tests.rs | ||
6 | --- | ||
7 | [10; 11) 'x': [unknown] | ||
8 | [21; 30) '{ x }': [unknown] | ||
9 | [27; 28) 'x': [unknown] | ||
10 | [44; 45) 'x': &[unknown] | ||
11 | [56; 65) '{ x }': &[unknown] | ||
12 | [62; 63) 'x': &[unknown] | ||
13 | [77; 157) '{ ...(1); }': () | ||
14 | [87; 88) 'y': u32 | ||
15 | [91; 96) '10u32': u32 | ||
16 | [102; 104) 'id': fn id<u32>(T) -> T | ||
17 | [102; 107) 'id(y)': u32 | ||
18 | [105; 106) 'y': u32 | ||
19 | [117; 118) 'x': bool | ||
20 | [127; 132) 'clone': fn clone<bool>(&T) -> T | ||
21 | [127; 135) 'clone(z)': bool | ||
22 | [133; 134) 'z': &bool | ||
23 | [141; 151) 'id::<i128>': fn id<i128>(T) -> T | ||
24 | [141; 154) 'id::<i128>(1)': i128 | ||
25 | [152; 153) '1': i128 | ||
26 | |||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index f74d6f5ea..ac12d974b 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -594,6 +594,29 @@ fn test() { | |||
594 | ); | 594 | ); |
595 | } | 595 | } |
596 | 596 | ||
597 | #[test] | ||
598 | fn infer_type_param() { | ||
599 | check_inference( | ||
600 | "infer_type_param", | ||
601 | r#" | ||
602 | fn id<T>(x: T) -> T { | ||
603 | x | ||
604 | } | ||
605 | |||
606 | fn clone<T>(x: &T) -> T { | ||
607 | x | ||
608 | } | ||
609 | |||
610 | fn test() { | ||
611 | let y = 10u32; | ||
612 | id(y); | ||
613 | let x: bool = clone(z); | ||
614 | id::<i128>(1); | ||
615 | } | ||
616 | "#, | ||
617 | ); | ||
618 | } | ||
619 | |||
597 | fn infer(content: &str) -> String { | 620 | fn infer(content: &str) -> String { |
598 | let (db, _, file_id) = MockDatabase::with_single_file(content); | 621 | let (db, _, file_id) = MockDatabase::with_single_file(content); |
599 | let source_file = db.parse(file_id); | 622 | let source_file = db.parse(file_id); |