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.rs102
1 files changed, 64 insertions, 38 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 3cf3eaded..9332aca9a 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -34,7 +34,7 @@ use test_utils::tested_by;
34 34
35use crate::{ 35use crate::{
36 Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, 36 Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
37 FnScopes, ModuleDef, AdtDef, 37 FnSignature, FnScopes, ModuleDef, AdtDef,
38 db::HirDatabase, 38 db::HirDatabase,
39 type_ref::{TypeRef, Mutability}, 39 type_ref::{TypeRef, Mutability},
40 name::KnownName, 40 name::KnownName,
@@ -225,6 +225,8 @@ pub enum Ty {
225 def: Function, 225 def: Function,
226 /// For display 226 /// For display
227 name: Name, 227 name: Name,
228 /// Parameters and return type
229 sig: Arc<FnSig>,
228 /// Substitutions for the generic parameters of the type 230 /// Substitutions for the generic parameters of the type
229 substs: Substs, 231 substs: Substs,
230 }, 232 },
@@ -544,7 +546,12 @@ impl Ty {
544 name, 546 name,
545 substs, 547 substs,
546 }, 548 },
547 Ty::FnDef { def, name, .. } => Ty::FnDef { def, name, substs }, 549 Ty::FnDef { def, name, sig, .. } => Ty::FnDef {
550 def,
551 name,
552 sig,
553 substs,
554 },
548 _ => self, 555 _ => self,
549 } 556 }
550 } 557 }
@@ -607,7 +614,9 @@ impl fmt::Display for Ty {
607 .to_fmt(f)?; 614 .to_fmt(f)?;
608 write!(f, " -> {}", sig.output) 615 write!(f, " -> {}", sig.output)
609 } 616 }
610 Ty::FnDef { name, substs, .. } => { 617 Ty::FnDef {
618 name, substs, sig, ..
619 } => {
611 // don't have access to the param types here :-( 620 // don't have access to the param types here :-(
612 // we could store them in the def, but not sure if it 621 // we could store them in the def, but not sure if it
613 // is worth it 622 // is worth it
@@ -618,7 +627,11 @@ impl fmt::Display for Ty {
618 .separator(", ") 627 .separator(", ")
619 .to_fmt(f)?; 628 .to_fmt(f)?;
620 } 629 }
621 Ok(()) 630 join(sig.input.iter())
631 .surround_with("(", ")")
632 .separator(", ")
633 .to_fmt(f)?;
634 write!(f, " -> {}", sig.output)
622 } 635 }
623 Ty::Adt { name, substs, .. } => { 636 Ty::Adt { name, substs, .. } => {
624 write!(f, "{}", name)?; 637 write!(f, "{}", name)?;
@@ -641,12 +654,29 @@ impl fmt::Display for Ty {
641 654
642/// Compute the declared type of a function. This should not need to look at the 655/// Compute the declared type of a function. This should not need to look at the
643/// function body. 656/// function body.
644fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { 657fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
645 let generics = f.generic_params(db); 658 let signature = def.signature(db);
659 let module = def.module(db);
660 let impl_block = def.impl_block(db);
661 let generics = def.generic_params(db);
662 let input = signature
663 .params()
664 .iter()
665 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr))
666 .collect::<Vec<_>>();
667 let output = Ty::from_hir(
668 db,
669 &module,
670 impl_block.as_ref(),
671 &generics,
672 signature.ret_type(),
673 );
674 let sig = Arc::new(FnSig { input, output });
646 let substs = make_substs(&generics); 675 let substs = make_substs(&generics);
647 let name = f.name(db); 676 let name = def.name(db);
648 Ty::FnDef { 677 Ty::FnDef {
649 def: f.into(), 678 def,
679 sig,
650 name, 680 name,
651 substs, 681 substs,
652 } 682 }
@@ -923,7 +953,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
923 self.type_of_pat.insert(pat, ty); 953 self.type_of_pat.insert(pat, ty);
924 } 954 }
925 955
926 fn make_ty(&mut self, type_ref: &TypeRef, generics: &GenericParams) -> Ty { 956 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
957 // TODO provide generics of function
958 let generics = GenericParams::default();
927 let ty = Ty::from_hir( 959 let ty = Ty::from_hir(
928 self.db, 960 self.db,
929 &self.module, 961 &self.module,
@@ -1337,7 +1369,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1337 1369
1338 for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { 1370 for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) {
1339 let expected = if let Some(type_ref) = arg_type { 1371 let expected = if let Some(type_ref) = arg_type {
1340 let ty = self.make_ty(type_ref, &GenericParams::default()); 1372 let ty = self.make_ty(type_ref);
1341 ty 1373 ty
1342 } else { 1374 } else {
1343 Ty::Unknown 1375 Ty::Unknown
@@ -1355,16 +1387,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1355 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 1387 let callee_ty = self.infer_expr(*callee, &Expectation::none());
1356 let (param_tys, ret_ty) = match &callee_ty { 1388 let (param_tys, ret_ty) = match &callee_ty {
1357 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), 1389 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
1358 Ty::FnDef { def, substs, .. } => { 1390 Ty::FnDef {
1359 let fn_sig = def.signature(self.db); 1391 def, substs, sig, ..
1360 let generic_params = def.generic_params(self.db); 1392 } => {
1361 let ret_ty = self 1393 let ret_ty = sig.output.clone().subst(&substs);
1362 .make_ty(fn_sig.ret_type(), &generic_params) 1394 let param_tys = sig
1363 .subst(&substs); 1395 .input
1364 let param_tys = fn_sig
1365 .params()
1366 .iter() 1396 .iter()
1367 .map(|type_ref| self.make_ty(type_ref, &generic_params).subst(&substs)) 1397 .map(|ty| ty.clone().subst(&substs))
1368 .collect(); 1398 .collect();
1369 (param_tys, ret_ty) 1399 (param_tys, ret_ty)
1370 } 1400 }
@@ -1407,17 +1437,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1407 (Ty::Unknown, Vec::new(), sig.output.clone()) 1437 (Ty::Unknown, Vec::new(), sig.output.clone())
1408 } 1438 }
1409 } 1439 }
1410 Ty::FnDef { def, substs, .. } => { 1440 Ty::FnDef {
1411 let fn_sig = def.signature(self.db); 1441 def, substs, sig, ..
1412 let generic_params = def.generic_params(self.db); 1442 } => {
1413 let ret_ty = self 1443 let ret_ty = sig.output.clone().subst(&substs);
1414 .make_ty(fn_sig.ret_type(), &generic_params) 1444
1415 .subst(&substs); 1445 if sig.input.len() > 0 {
1416 1446 let mut arg_iter = sig.input.iter().map(|ty| ty.clone().subst(&substs));
1417 if fn_sig.params().len() > 0 {
1418 let mut arg_iter = fn_sig.params().iter().map(|type_ref| {
1419 self.make_ty(type_ref, &generic_params).subst(&substs)
1420 });
1421 let receiver_ty = arg_iter.next().unwrap(); 1447 let receiver_ty = arg_iter.next().unwrap();
1422 (receiver_ty, arg_iter.collect(), ret_ty) 1448 (receiver_ty, arg_iter.collect(), ret_ty)
1423 } else { 1449 } else {
@@ -1515,7 +1541,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1515 } 1541 }
1516 Expr::Cast { expr, type_ref } => { 1542 Expr::Cast { expr, type_ref } => {
1517 let _inner_ty = self.infer_expr(*expr, &Expectation::none()); 1543 let _inner_ty = self.infer_expr(*expr, &Expectation::none());
1518 let cast_ty = self.make_ty(type_ref, &GenericParams::default()); 1544 let cast_ty = self.make_ty(type_ref);
1519 // TODO check the cast... 1545 // TODO check the cast...
1520 cast_ty 1546 cast_ty
1521 } 1547 }
@@ -1629,7 +1655,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1629 } => { 1655 } => {
1630 let decl_ty = type_ref 1656 let decl_ty = type_ref
1631 .as_ref() 1657 .as_ref()
1632 .map(|tr| self.make_ty(tr, &GenericParams::default())) 1658 .map(|tr| self.make_ty(tr))
1633 .unwrap_or(Ty::Unknown); 1659 .unwrap_or(Ty::Unknown);
1634 let decl_ty = self.insert_type_vars(decl_ty); 1660 let decl_ty = self.insert_type_vars(decl_ty);
1635 let ty = if let Some(expr) = initializer { 1661 let ty = if let Some(expr) = initializer {
@@ -1654,16 +1680,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1654 ty 1680 ty
1655 } 1681 }
1656 1682
1657 fn collect_fn_signature(&mut self, func: Function) { 1683 fn collect_fn_signature(&mut self, signature: &FnSignature) {
1658 let body = Arc::clone(&self.body); // avoid borrow checker problem 1684 let body = Arc::clone(&self.body); // avoid borrow checker problem
1659 let signature = func.signature(self.db);
1660 let generics = func.generic_params(self.db);
1661 for (type_ref, pat) in signature.params().iter().zip(body.params()) { 1685 for (type_ref, pat) in signature.params().iter().zip(body.params()) {
1662 let ty = self.make_ty(type_ref, &generics); 1686 let ty = self.make_ty(type_ref);
1663 1687
1664 self.infer_pat(*pat, &ty); 1688 self.infer_pat(*pat, &ty);
1665 } 1689 }
1666 self.return_ty = self.make_ty(signature.ret_type(), &generics); 1690 self.return_ty = self.make_ty(signature.ret_type());
1667 } 1691 }
1668 1692
1669 fn infer_body(&mut self) { 1693 fn infer_body(&mut self) {
@@ -1682,7 +1706,9 @@ pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
1682 let impl_block = func.impl_block(db); 1706 let impl_block = func.impl_block(db);
1683 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); 1707 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);
1684 1708
1685 ctx.collect_fn_signature(func); 1709 let signature = func.signature(db);
1710 ctx.collect_fn_signature(&signature);
1711
1686 ctx.infer_body(); 1712 ctx.infer_body();
1687 1713
1688 Arc::new(ctx.resolve_all()) 1714 Arc::new(ctx.resolve_all())