aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-25 23:30:56 +0000
committerMarcus Klaas de Vries <[email protected]>2019-01-27 16:59:21 +0000
commitaa06893a1493770f8009d098a5340f1a9ba13dec (patch)
treeaebdb8ce81e007be4c45ee7b051df97e9ecb8280 /crates/ra_hir/src/ty.rs
parent67e40e431aa966a76b6a247b19505e22b620a0c7 (diff)
Add type params to FnSignature
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs126
1 files changed, 45 insertions, 81 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 9b08b9c97..43181ffc9 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};
@@ -225,7 +226,7 @@ pub enum Ty {
225 /// For display 226 /// For display
226 name: Name, 227 name: Name,
227 /// Substitutions for the generic parameters of the type 228 /// Substitutions for the generic parameters of the type
228 substs: Substs 229 substs: Substs,
229 }, 230 },
230 231
231 /// A pointer to a function. Written as `fn() -> i32`. 232 /// A pointer to a function. Written as `fn() -> i32`.
@@ -543,11 +544,7 @@ impl Ty {
543 name, 544 name,
544 substs, 545 substs,
545 }, 546 },
546 Ty::FnDef { def, name, .. } => Ty::FnDef { 547 Ty::FnDef { def, name, .. } => Ty::FnDef { def, name, substs },
547 def,
548 name,
549 substs,
550 },
551 _ => self, 548 _ => self,
552 } 549 }
553 } 550 }
@@ -651,30 +648,10 @@ fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty {
651 Ty::FnDef { 648 Ty::FnDef {
652 def: f.into(), 649 def: f.into(),
653 name, 650 name,
654 substs 651 substs,
655 } 652 }
656} 653}
657 654
658fn get_func_sig(db: &impl HirDatabase, f: Function) -> FnSig {
659 let signature = f.signature(db);
660 let module = f.module(db);
661 let impl_block = f.impl_block(db);
662 let generics = f.generic_params(db);
663 let input = signature
664 .args()
665 .iter()
666 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr))
667 .collect::<Vec<_>>();
668 let output = Ty::from_hir(
669 db,
670 &module,
671 impl_block.as_ref(),
672 &generics,
673 signature.ret_type(),
674 );
675 FnSig { input, output }
676}
677
678fn make_substs(generics: &GenericParams) -> Substs { 655fn make_substs(generics: &GenericParams) -> Substs {
679 Substs( 656 Substs(
680 generics 657 generics
@@ -946,9 +923,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
946 self.type_of_pat.insert(pat, ty); 923 self.type_of_pat.insert(pat, ty);
947 } 924 }
948 925
949 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { 926 fn make_ty(&mut self, type_ref: &TypeRef, generics: &GenericParams) -> Ty {
950 // TODO provide generics of function
951 let generics = GenericParams::default();
952 let ty = Ty::from_hir( 927 let ty = Ty::from_hir(
953 self.db, 928 self.db,
954 &self.module, 929 &self.module,
@@ -1249,9 +1224,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1249 Ty::Tuple(ref tuple_args) => &**tuple_args, 1224 Ty::Tuple(ref tuple_args) => &**tuple_args,
1250 _ => &[], 1225 _ => &[],
1251 }; 1226 };
1252 let expectations_iter = expectations 1227 let expectations_iter = expectations.into_iter().chain(repeat(&Ty::Unknown));
1253 .into_iter()
1254 .chain(std::iter::repeat(&Ty::Unknown));
1255 1228
1256 let inner_tys = args 1229 let inner_tys = args
1257 .iter() 1230 .iter()
@@ -1370,7 +1343,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1370 1343
1371 for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { 1344 for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) {
1372 let expected = if let Some(type_ref) = arg_type { 1345 let expected = if let Some(type_ref) = arg_type {
1373 let ty = self.make_ty(type_ref); 1346 let ty = self.make_ty(type_ref, &GenericParams::default());
1374 ty 1347 ty
1375 } else { 1348 } else {
1376 Ty::Unknown 1349 Ty::Unknown
@@ -1386,22 +1359,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1386 // TODO: we should use turbofish hints like this: 1359 // TODO: we should use turbofish hints like this:
1387 // f::<u32>(x) 1360 // f::<u32>(x)
1388 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 1361 let callee_ty = self.infer_expr(*callee, &Expectation::none());
1389 // FIXME: so manu unnecessary clones
1390 let (param_tys, ret_ty) = match &callee_ty { 1362 let (param_tys, ret_ty) = match &callee_ty {
1391 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), 1363 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
1392 Ty::FnDef { def, substs, .. } => { 1364 Ty::FnDef { def, substs, .. } => {
1393 let fn_sig = def.signature(self.db); 1365 let fn_sig = def.signature(self.db);
1394 // TODO: get input and return types from the fn_sig. 1366 let ret_ty = self
1395 // it contains typerefs which we can make into proper tys 1367 .make_ty(fn_sig.ret_type(), fn_sig.generics())
1396 1368 .subst(&substs);
1397 let sig = get_func_sig(self.db, *def); 1369 let param_tys = fn_sig
1398 ( 1370 .args()
1399 sig.input 1371 .iter()
1400 .iter() 1372 .map(|type_ref| {
1401 .map(|ty| ty.clone().subst(&substs)) 1373 self.make_ty(type_ref, fn_sig.generics()).subst(&substs)
1402 .collect(), 1374 })
1403 sig.output.clone().subst(&substs), 1375 .collect();
1404 ) 1376 (param_tys, ret_ty)
1405 } 1377 }
1406 _ => { 1378 _ => {
1407 // not callable 1379 // not callable
@@ -1409,11 +1381,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1409 (Vec::new(), Ty::Unknown) 1381 (Vec::new(), Ty::Unknown)
1410 } 1382 }
1411 }; 1383 };
1412 for (i, arg) in args.iter().enumerate() { 1384 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
1413 self.infer_expr( 1385 for (arg, param) in args.iter().zip(param_iter) {
1414 *arg, 1386 self.infer_expr(*arg, &Expectation::has_type(param));
1415 &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)),
1416 );
1417 } 1387 }
1418 ret_ty 1388 ret_ty
1419 } 1389 }
@@ -1435,46 +1405,39 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1435 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { 1405 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
1436 Ty::FnPtr(sig) => { 1406 Ty::FnPtr(sig) => {
1437 if sig.input.len() > 0 { 1407 if sig.input.len() > 0 {
1438 (sig.input[0].clone(), sig.input[1..].iter().cloned().collect(), sig.output.clone()) 1408 (
1409 sig.input[0].clone(),
1410 sig.input[1..].iter().cloned().collect(),
1411 sig.output.clone(),
1412 )
1439 } else { 1413 } else {
1440 (Ty::Unknown, Vec::new(), sig.output.clone()) 1414 (Ty::Unknown, Vec::new(), sig.output.clone())
1441 } 1415 }
1442 } 1416 }
1443 Ty::FnDef { def, substs, .. } => { 1417 Ty::FnDef { def, substs, .. } => {
1444 // TODO: fix deduplication with Expr::Call block above
1445 // TODO: fix the ridiculous number of clones
1446 let fn_sig = def.signature(self.db); 1418 let fn_sig = def.signature(self.db);
1447 // TODO: get input and return types from the fn_sig. 1419 let ret_ty = self
1448 // it contains typerefs which we can make into proper tys 1420 .make_ty(fn_sig.ret_type(), fn_sig.generics())
1449 1421 .subst(&substs);
1450 // check that len > 0 1422
1451 let sig = get_func_sig(self.db, *def); 1423 if fn_sig.args().len() > 0 {
1452 if sig.input.len() > 0 { 1424 let mut arg_iter = fn_sig.args().iter().map(|type_ref| {
1453 ( 1425 self.make_ty(type_ref, fn_sig.generics()).subst(&substs)
1454 sig.input[0].clone().subst(&substs), 1426 });
1455 sig.input[1..] 1427 let receiver_ty = arg_iter.next().unwrap();
1456 .iter() 1428 (receiver_ty, arg_iter.collect(), ret_ty)
1457 .map(|ty| ty.clone().subst(&substs))
1458 .collect(),
1459 sig.output.clone().subst(&substs),
1460 )
1461 } else { 1429 } else {
1462 (Ty::Unknown, Vec::new(), sig.output.clone()) 1430 (Ty::Unknown, Vec::new(), ret_ty)
1463 } 1431 }
1464 } 1432 }
1465 _ => (Ty::Unknown, Vec::new(), Ty::Unknown), 1433 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
1466 }; 1434 };
1467 // TODO we would have to apply the autoderef/autoref steps here 1435 // TODO we would have to apply the autoderef/autoref steps here
1468 // to get the correct receiver type to unify... 1436 // to get the correct receiver type to unify...
1469 //
1470 // TODO: zip param_tys.chain(iter::repeat(Ty::Unknown)) above then its not so bad
1471 // that we clone
1472 self.unify(&expected_receiver_ty, &receiver_ty); 1437 self.unify(&expected_receiver_ty, &receiver_ty);
1473 for (i, arg) in args.iter().enumerate() { 1438 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
1474 self.infer_expr( 1439 for (arg, param) in args.iter().zip(param_iter) {
1475 *arg, 1440 self.infer_expr(*arg, &Expectation::has_type(param));
1476 &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)),
1477 );
1478 } 1441 }
1479 ret_ty 1442 ret_ty
1480 } 1443 }
@@ -1558,7 +1521,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1558 } 1521 }
1559 Expr::Cast { expr, type_ref } => { 1522 Expr::Cast { expr, type_ref } => {
1560 let _inner_ty = self.infer_expr(*expr, &Expectation::none()); 1523 let _inner_ty = self.infer_expr(*expr, &Expectation::none());
1561 let cast_ty = self.make_ty(type_ref); 1524 let cast_ty = self.make_ty(type_ref, &GenericParams::default());
1562 // TODO check the cast... 1525 // TODO check the cast...
1563 cast_ty 1526 cast_ty
1564 } 1527 }
@@ -1672,7 +1635,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1672 } => { 1635 } => {
1673 let decl_ty = type_ref 1636 let decl_ty = type_ref
1674 .as_ref() 1637 .as_ref()
1675 .map(|tr| self.make_ty(tr)) 1638 .map(|tr| self.make_ty(tr, &GenericParams::default()))
1676 .unwrap_or(Ty::Unknown); 1639 .unwrap_or(Ty::Unknown);
1677 let decl_ty = self.insert_type_vars(decl_ty); 1640 let decl_ty = self.insert_type_vars(decl_ty);
1678 let ty = if let Some(expr) = initializer { 1641 let ty = if let Some(expr) = initializer {
@@ -1699,12 +1662,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1699 1662
1700 fn collect_fn_signature(&mut self, signature: &FnSignature) { 1663 fn collect_fn_signature(&mut self, signature: &FnSignature) {
1701 let body = Arc::clone(&self.body); // avoid borrow checker problem 1664 let body = Arc::clone(&self.body); // avoid borrow checker problem
1665 let generics = signature.generics();
1702 for (type_ref, pat) in signature.args().iter().zip(body.params()) { 1666 for (type_ref, pat) in signature.args().iter().zip(body.params()) {
1703 let ty = self.make_ty(type_ref); 1667 let ty = self.make_ty(type_ref, generics);
1704 1668
1705 self.infer_pat(*pat, &ty); 1669 self.infer_pat(*pat, &ty);
1706 } 1670 }
1707 self.return_ty = self.make_ty(signature.ret_type()); 1671 self.return_ty = self.make_ty(signature.ret_type(), generics);
1708 } 1672 }
1709 1673
1710 fn infer_body(&mut self) { 1674 fn infer_body(&mut self) {