aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model_api.rs4
-rw-r--r--crates/ra_hir/src/ty.rs162
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap8
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap8
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap24
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap46
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap10
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap26
-rw-r--r--crates/ra_hir/src/ty/tests.rs23
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;
20pub(crate) mod method_resolution; 20pub(crate) mod method_resolution;
21 21
22use std::borrow::Cow; 22use std::borrow::Cow;
23use std::iter::repeat;
23use std::ops::Index; 24use std::ops::Index;
24use std::sync::Arc; 25use std::sync::Arc;
25use std::{fmt, mem}; 26use 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.
610fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { 667fn 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
631fn make_substs(generics: &GenericParams) -> Substs { 695fn 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---
2created: "2019-01-22T14:44:59.880187500+00:00" 2created: "2019-01-26T17:46:03.842478456+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: 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---
2created: "2019-01-22T14:44:59.880187500+00:00" 2created: "2019-01-26T17:46:03.853259898+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: 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---
2created: "2019-01-22T14:44:59.954958500+00:00" 2created: "2019-01-26T18:16:16.530712344+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: 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---
2created: "2019-01-22T14:44:59.961936900+00:00" 2created: "2019-01-26T17:46:03.866825843+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: 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---
2created: "2019-01-22T14:44:59.975899500+00:00" 2created: "2019-01-26T17:46:03.928773630+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: 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---
2created: "2019-01-27T16:54:18.368427685+00:00"
3creator: [email protected]
4expression: "&result"
5source: 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]
598fn infer_type_param() {
599 check_inference(
600 "infer_type_param",
601 r#"
602fn id<T>(x: T) -> T {
603 x
604}
605
606fn clone<T>(x: &T) -> T {
607 x
608}
609
610fn test() {
611 let y = 10u32;
612 id(y);
613 let x: bool = clone(z);
614 id::<i128>(1);
615}
616"#,
617 );
618}
619
597fn infer(content: &str) -> String { 620fn 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);