aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/ty.rs63
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap (renamed from crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap)10
-rw-r--r--crates/ra_hir/src/ty/tests.rs6
3 files changed, 35 insertions, 44 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 00a71a42f..37715a903 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -470,12 +470,12 @@ impl Ty {
470 } 470 }
471 // add placeholders for args that were not provided 471 // add placeholders for args that were not provided
472 // TODO: handle defaults 472 // TODO: handle defaults
473 for _ in segment 473 let supplied_params = segment
474 .args_and_bindings 474 .args_and_bindings
475 .as_ref() 475 .as_ref()
476 .map(|ga| ga.args.len()) 476 .map(|ga| ga.args.len())
477 .unwrap_or(0)..def_generics.params.len() 477 .unwrap_or(0);
478 { 478 for _ in supplied_params..def_generics.params.len() {
479 substs.push(Ty::Unknown); 479 substs.push(Ty::Unknown);
480 } 480 }
481 assert_eq!(substs.len(), def_generics.params.len()); 481 assert_eq!(substs.len(), def_generics.params.len());
@@ -507,7 +507,20 @@ impl Ty {
507 } 507 }
508 sig_mut.output.walk_mut(f); 508 sig_mut.output.walk_mut(f);
509 } 509 }
510 Ty::FnDef { substs, .. } | Ty::Adt { substs, .. } => { 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 }
523 Ty::Adt { substs, .. } => {
511 // 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:
512 let mut v: Vec<_> = substs.0.iter().cloned().collect(); 525 let mut v: Vec<_> = substs.0.iter().cloned().collect();
513 for t in &mut v { 526 for t in &mut v {
@@ -579,7 +592,7 @@ impl Ty {
579 /// 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`.
580 fn substs(&self) -> Option<Substs> { 593 fn substs(&self) -> Option<Substs> {
581 match self { 594 match self {
582 Ty::Adt { substs, .. } => Some(substs.clone()), 595 Ty::Adt { substs, .. } | Ty::FnDef { substs, .. } => Some(substs.clone()),
583 _ => None, 596 _ => None,
584 } 597 }
585 } 598 }
@@ -617,9 +630,6 @@ impl fmt::Display for Ty {
617 Ty::FnDef { 630 Ty::FnDef {
618 name, substs, sig, .. 631 name, substs, sig, ..
619 } => { 632 } => {
620 // don't have access to the param types here :-(
621 // we could store them in the def, but not sure if it
622 // is worth it
623 write!(f, "fn {}", name)?; 633 write!(f, "fn {}", name)?;
624 if substs.0.len() > 0 { 634 if substs.0.len() > 0 {
625 join(substs.0.iter()) 635 join(substs.0.iter())
@@ -1156,33 +1166,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1156 .into(); 1166 .into();
1157 let typable = typable?; 1167 let typable = typable?;
1158 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);
1159 let ty = self.insert_type_vars(ty); 1179 let ty = self.insert_type_vars(ty);
1160 1180
1161 // try to get generic parameters from the path and add them to the
1162 // function type substitutions
1163 if let Ty::FnDef { ref def, .. } = ty {
1164 let last_seg_bindings = path
1165 .segments
1166 .last()
1167 .and_then(|segment| segment.args_and_bindings.as_ref());
1168 if let Some(generic_args) = last_seg_bindings {
1169 let generic_params = def.generic_params(self.db);
1170 if generic_args.args.len() == generic_params.params.len() {
1171 let substs = Ty::substs_from_path(
1172 self.db,
1173 &self.module,
1174 self.impl_block.as_ref(),
1175 &generic_params,
1176 path,
1177 (*def).into(),
1178 );
1179 return Some(ty.apply_substs(substs));
1180 } else {
1181 // ERROR: incorrect number of type params
1182 }
1183 }
1184 }
1185
1186 Some(ty) 1181 Some(ty)
1187 } 1182 }
1188 1183
@@ -1408,8 +1403,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1408 Ty::Unknown 1403 Ty::Unknown
1409 } 1404 }
1410 Expr::Call { callee, args } => { 1405 Expr::Call { callee, args } => {
1411 // TODO: we should use turbofish hints like this:
1412 // f::<u32>(x)
1413 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 1406 let callee_ty = self.infer_expr(*callee, &Expectation::none());
1414 let (param_tys, ret_ty) = match &callee_ty { 1407 let (param_tys, ret_ty) = match &callee_ty {
1415 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), 1408 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
diff --git a/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap
index 85aeefa0c..a99323264 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap
@@ -1,5 +1,5 @@
1--- 1---
2created: "2019-01-26T18:16:16.568375+00:00" 2created: "2019-01-27T16:54:18.368427685+00:00"
3creator: [email protected] 3creator: [email protected]
4expression: "&result" 4expression: "&result"
5source: crates/ra_hir/src/ty/tests.rs 5source: crates/ra_hir/src/ty/tests.rs
@@ -10,7 +10,7 @@ source: crates/ra_hir/src/ty/tests.rs
10[44; 45) 'x': &[unknown] 10[44; 45) 'x': &[unknown]
11[56; 65) '{ x }': &[unknown] 11[56; 65) '{ x }': &[unknown]
12[62; 63) 'x': &[unknown] 12[62; 63) 'x': &[unknown]
13[77; 197) '{ ...(1); }': () 13[77; 157) '{ ...(1); }': ()
14[87; 88) 'y': u32 14[87; 88) 'y': u32
15[91; 96) '10u32': u32 15[91; 96) '10u32': u32
16[102; 104) 'id': fn id<u32>(T) -> T 16[102; 104) 'id': fn id<u32>(T) -> T
@@ -20,7 +20,7 @@ source: crates/ra_hir/src/ty/tests.rs
20[127; 132) 'clone': fn clone<bool>(&T) -> T 20[127; 132) 'clone': fn clone<bool>(&T) -> T
21[127; 135) 'clone(z)': bool 21[127; 135) 'clone(z)': bool
22[133; 134) 'z': &bool 22[133; 134) 'z': &bool
23[173; 191) 'id::<i...tring>': fn id<i32>(T) -> T 23[141; 151) 'id::<i128>': fn id<i128>(T) -> T
24[173; 194) 'id::<i...ng>(1)': i32 24[141; 154) 'id::<i128>(1)': i128
25[192; 193) '1': i32 25[152; 153) '1': i128
26 26
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index fac566626..ac12d974b 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -597,7 +597,7 @@ fn test() {
597#[test] 597#[test]
598fn infer_type_param() { 598fn infer_type_param() {
599 check_inference( 599 check_inference(
600 "generic_fn", 600 "infer_type_param",
601 r#" 601 r#"
602fn id<T>(x: T) -> T { 602fn id<T>(x: T) -> T {
603 x 603 x
@@ -611,9 +611,7 @@ fn test() {
611 let y = 10u32; 611 let y = 10u32;
612 id(y); 612 id(y);
613 let x: bool = clone(z); 613 let x: bool = clone(z);
614 614 id::<i128>(1);
615 // bad turbofish - ignore!
616 id::<i128, String>(1);
617} 615}
618"#, 616"#,
619 ); 617 );