diff options
author | Marcus Klaas de Vries <[email protected]> | 2019-01-25 23:30:56 +0000 |
---|---|---|
committer | Marcus Klaas de Vries <[email protected]> | 2019-01-27 16:59:21 +0000 |
commit | aa06893a1493770f8009d098a5340f1a9ba13dec (patch) | |
tree | aebdb8ce81e007be4c45ee7b051df97e9ecb8280 /crates/ra_hir/src/ty.rs | |
parent | 67e40e431aa966a76b6a247b19505e22b620a0c7 (diff) |
Add type params to FnSignature
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 126 |
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; | |||
20 | pub(crate) mod method_resolution; | 20 | pub(crate) mod method_resolution; |
21 | 21 | ||
22 | use std::borrow::Cow; | 22 | use std::borrow::Cow; |
23 | use std::iter::repeat; | ||
23 | use std::ops::Index; | 24 | use std::ops::Index; |
24 | use std::sync::Arc; | 25 | use std::sync::Arc; |
25 | use std::{fmt, mem}; | 26 | use 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 | ||
658 | fn 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 | |||
678 | fn make_substs(generics: &GenericParams) -> Substs { | 655 | fn 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) { |