aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs61
1 files changed, 49 insertions, 12 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 31ea45706..95de916ee 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -209,6 +209,18 @@ pub enum Ty {
209 /// `&'a mut T` or `&'a T`. 209 /// `&'a mut T` or `&'a T`.
210 Ref(Arc<Ty>, Mutability), 210 Ref(Arc<Ty>, Mutability),
211 211
212 /// The anonymous type of a function declaration/definition. Each
213 /// function has a unique type, which is output (for a function
214 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
215 ///
216 /// For example the type of `bar` here:
217 ///
218 /// ```rust
219 /// fn foo() -> i32 { 1 }
220 /// let bar = foo; // bar: fn() -> i32 {foo}
221 /// ```
222 FnDef(Function, Substs),
223
212 /// A pointer to a function. Written as `fn() -> i32`. 224 /// A pointer to a function. Written as `fn() -> i32`.
213 /// 225 ///
214 /// For example the type of `bar` here: 226 /// For example the type of `bar` here:
@@ -485,7 +497,7 @@ impl Ty {
485 } 497 }
486 sig_mut.output.walk_mut(f); 498 sig_mut.output.walk_mut(f);
487 } 499 }
488 Ty::Adt { substs, .. } => { 500 Ty::FnDef(_, substs) | Ty::Adt { substs, .. } => {
489 // Without an Arc::make_mut_slice, we can't avoid the clone here: 501 // Without an Arc::make_mut_slice, we can't avoid the clone here:
490 let mut v: Vec<_> = substs.0.iter().cloned().collect(); 502 let mut v: Vec<_> = substs.0.iter().cloned().collect();
491 for t in &mut v { 503 for t in &mut v {
@@ -524,6 +536,7 @@ impl Ty {
524 name, 536 name,
525 substs, 537 substs,
526 }, 538 },
539 Ty::FnDef(func, _) => Ty::FnDef(func, substs),
527 _ => self, 540 _ => self,
528 } 541 }
529 } 542 }
@@ -579,6 +592,7 @@ impl fmt::Display for Ty {
579 .to_fmt(f) 592 .to_fmt(f)
580 } 593 }
581 } 594 }
595 Ty::FnDef(_func, _substs) => write!(f, "FNDEF-IMPLEMENT-ME"),
582 Ty::FnPtr(sig) => { 596 Ty::FnPtr(sig) => {
583 join(sig.input.iter()) 597 join(sig.input.iter())
584 .surround_with("fn(", ")") 598 .surround_with("fn(", ")")
@@ -608,12 +622,18 @@ impl fmt::Display for Ty {
608/// Compute the declared type of a function. This should not need to look at the 622/// Compute the declared type of a function. This should not need to look at the
609/// function body. 623/// function body.
610fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { 624fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty {
625 let generics = f.generic_params(db);
626 let substs = make_substs(&generics);
627 Ty::FnDef(f.into(), substs)
628}
629
630fn get_func_sig(db: &impl HirDatabase, f: Function) -> FnSig {
611 let signature = f.signature(db); 631 let signature = f.signature(db);
612 let module = f.module(db); 632 let module = f.module(db);
613 let impl_block = f.impl_block(db); 633 let impl_block = f.impl_block(db);
614 let generics = f.generic_params(db); 634 let generics = f.generic_params(db);
615 let input = signature 635 let input = signature
616 .params() 636 .args()
617 .iter() 637 .iter()
618 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr)) 638 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr))
619 .collect::<Vec<_>>(); 639 .collect::<Vec<_>>();
@@ -624,8 +644,7 @@ fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty {
624 &generics, 644 &generics,
625 signature.ret_type(), 645 signature.ret_type(),
626 ); 646 );
627 let sig = FnSig { input, output }; 647 FnSig { input, output }
628 Ty::FnPtr(Arc::new(sig))
629} 648}
630 649
631fn make_substs(generics: &GenericParams) -> Substs { 650fn make_substs(generics: &GenericParams) -> Substs {
@@ -1142,7 +1161,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1142 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1161 let ty = self.insert_type_vars(ty.apply_substs(substs));
1143 (ty, Some(var.into())) 1162 (ty, Some(var.into()))
1144 } 1163 }
1145 TypableDef::Enum(_) | TypableDef::Function(_) => (Ty::Unknown, None), 1164 TypableDef::Function(func) => {
1165 let ty = type_for_fn(self.db, func);
1166 let ty = self.insert_type_vars(ty.apply_substs(substs));
1167 // FIXME: is this right?
1168 (ty, None)
1169 }
1170 TypableDef::Enum(_) => (Ty::Unknown, None),
1146 } 1171 }
1147 } 1172 }
1148 1173
@@ -1331,12 +1356,27 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1331 } 1356 }
1332 Expr::Call { callee, args } => { 1357 Expr::Call { callee, args } => {
1333 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 1358 let callee_ty = self.infer_expr(*callee, &Expectation::none());
1359 // FIXME: so manu unnecessary clones
1334 let (param_tys, ret_ty) = match &callee_ty { 1360 let (param_tys, ret_ty) = match &callee_ty {
1335 Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), 1361 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
1362 Ty::FnDef(func, substs) => {
1363 let fn_sig = func.signature(self.db);
1364 // TODO: get input and return types from the fn_sig.
1365 // it contains typerefs which we can make into proper tys
1366
1367 let sig = get_func_sig(self.db, *func);
1368 (
1369 sig.input
1370 .iter()
1371 .map(|ty| ty.clone().subst(&substs))
1372 .collect(),
1373 sig.output.clone().subst(&substs),
1374 )
1375 }
1336 _ => { 1376 _ => {
1337 // not callable 1377 // not callable
1338 // TODO report an error? 1378 // TODO report an error?
1339 (&[][..], Ty::Unknown) 1379 (Vec::new(), Ty::Unknown)
1340 } 1380 }
1341 }; 1381 };
1342 for (i, arg) in args.iter().enumerate() { 1382 for (i, arg) in args.iter().enumerate() {
@@ -1604,15 +1644,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1604 1644
1605 fn collect_fn_signature(&mut self, signature: &FnSignature) { 1645 fn collect_fn_signature(&mut self, signature: &FnSignature) {
1606 let body = Arc::clone(&self.body); // avoid borrow checker problem 1646 let body = Arc::clone(&self.body); // avoid borrow checker problem
1607 for (type_ref, pat) in signature.params().iter().zip(body.params()) { 1647 for (type_ref, pat) in signature.args().iter().zip(body.params()) {
1608 let ty = self.make_ty(type_ref); 1648 let ty = self.make_ty(type_ref);
1609 1649
1610 self.infer_pat(*pat, &ty); 1650 self.infer_pat(*pat, &ty);
1611 } 1651 }
1612 self.return_ty = { 1652 self.return_ty = self.make_ty(signature.ret_type());
1613 let ty = self.make_ty(signature.ret_type());
1614 ty
1615 };
1616 } 1653 }
1617 1654
1618 fn infer_body(&mut self) { 1655 fn infer_body(&mut self) {