diff options
-rw-r--r-- | crates/ra_hir/src/ty.rs | 63 | ||||
-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.rs | 6 |
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 | --- |
2 | created: "2019-01-26T18:16:16.568375+00:00" | 2 | created: "2019-01-27T16:54:18.368427685+00:00" |
3 | creator: [email protected] | 3 | creator: [email protected] |
4 | expression: "&result" | 4 | expression: "&result" |
5 | source: crates/ra_hir/src/ty/tests.rs | 5 | source: 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] |
598 | fn infer_type_param() { | 598 | fn infer_type_param() { |
599 | check_inference( | 599 | check_inference( |
600 | "generic_fn", | 600 | "infer_type_param", |
601 | r#" | 601 | r#" |
602 | fn id<T>(x: T) -> T { | 602 | fn 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 | ); |