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.rs196
1 files changed, 150 insertions, 46 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 31ea45706..60c231e82 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};
@@ -33,7 +34,7 @@ use test_utils::tested_by;
33 34
34use crate::{ 35use crate::{
35 Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, 36 Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
36 FnSignature, FnScopes, ModuleDef, AdtDef, 37 FnSignature, ExprScopes, ModuleDef, AdtDef,
37 db::HirDatabase, 38 db::HirDatabase,
38 type_ref::{TypeRef, Mutability}, 39 type_ref::{TypeRef, Mutability},
39 name::KnownName, 40 name::KnownName,
@@ -185,7 +186,7 @@ pub enum Ty {
185 186
186 /// Structures, enumerations and unions. 187 /// Structures, enumerations and unions.
187 Adt { 188 Adt {
188 /// The DefId of the struct/enum. 189 /// The definition of the struct/enum.
189 def_id: AdtDef, 190 def_id: AdtDef,
190 /// The name, for displaying. 191 /// The name, for displaying.
191 name: Name, 192 name: Name,
@@ -209,6 +210,27 @@ pub enum Ty {
209 /// `&'a mut T` or `&'a T`. 210 /// `&'a mut T` or `&'a T`.
210 Ref(Arc<Ty>, Mutability), 211 Ref(Arc<Ty>, Mutability),
211 212
213 /// The anonymous type of a function declaration/definition. Each
214 /// function has a unique type, which is output (for a function
215 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
216 ///
217 /// For example the type of `bar` here:
218 ///
219 /// ```rust
220 /// fn foo() -> i32 { 1 }
221 /// let bar = foo; // bar: fn() -> i32 {foo}
222 /// ```
223 FnDef {
224 // Function definition
225 def: Function,
226 /// For display
227 name: Name,
228 /// Parameters and return type
229 sig: Arc<FnSig>,
230 /// Substitutions for the generic parameters of the type
231 substs: Substs,
232 },
233
212 /// A pointer to a function. Written as `fn() -> i32`. 234 /// A pointer to a function. Written as `fn() -> i32`.
213 /// 235 ///
214 /// For example the type of `bar` here: 236 /// For example the type of `bar` here:
@@ -448,12 +470,12 @@ impl Ty {
448 } 470 }
449 // add placeholders for args that were not provided 471 // add placeholders for args that were not provided
450 // TODO: handle defaults 472 // TODO: handle defaults
451 for _ in segment 473 let supplied_params = segment
452 .args_and_bindings 474 .args_and_bindings
453 .as_ref() 475 .as_ref()
454 .map(|ga| ga.args.len()) 476 .map(|ga| ga.args.len())
455 .unwrap_or(0)..def_generics.params.len() 477 .unwrap_or(0);
456 { 478 for _ in supplied_params..def_generics.params.len() {
457 substs.push(Ty::Unknown); 479 substs.push(Ty::Unknown);
458 } 480 }
459 assert_eq!(substs.len(), def_generics.params.len()); 481 assert_eq!(substs.len(), def_generics.params.len());
@@ -485,6 +507,19 @@ impl Ty {
485 } 507 }
486 sig_mut.output.walk_mut(f); 508 sig_mut.output.walk_mut(f);
487 } 509 }
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 }
488 Ty::Adt { substs, .. } => { 523 Ty::Adt { substs, .. } => {
489 // 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:
490 let mut v: Vec<_> = substs.0.iter().cloned().collect(); 525 let mut v: Vec<_> = substs.0.iter().cloned().collect();
@@ -524,6 +559,12 @@ impl Ty {
524 name, 559 name,
525 substs, 560 substs,
526 }, 561 },
562 Ty::FnDef { def, name, sig, .. } => Ty::FnDef {
563 def,
564 name,
565 sig,
566 substs,
567 },
527 _ => self, 568 _ => self,
528 } 569 }
529 } 570 }
@@ -551,7 +592,7 @@ impl Ty {
551 /// 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`.
552 fn substs(&self) -> Option<Substs> { 593 fn substs(&self) -> Option<Substs> {
553 match self { 594 match self {
554 Ty::Adt { substs, .. } => Some(substs.clone()), 595 Ty::Adt { substs, .. } | Ty::FnDef { substs, .. } => Some(substs.clone()),
555 _ => None, 596 _ => None,
556 } 597 }
557 } 598 }
@@ -586,6 +627,22 @@ impl fmt::Display for Ty {
586 .to_fmt(f)?; 627 .to_fmt(f)?;
587 write!(f, " -> {}", sig.output) 628 write!(f, " -> {}", sig.output)
588 } 629 }
630 Ty::FnDef {
631 name, substs, sig, ..
632 } => {
633 write!(f, "fn {}", name)?;
634 if substs.0.len() > 0 {
635 join(substs.0.iter())
636 .surround_with("<", ">")
637 .separator(", ")
638 .to_fmt(f)?;
639 }
640 join(sig.input.iter())
641 .surround_with("(", ")")
642 .separator(", ")
643 .to_fmt(f)?;
644 write!(f, " -> {}", sig.output)
645 }
589 Ty::Adt { name, substs, .. } => { 646 Ty::Adt { name, substs, .. } => {
590 write!(f, "{}", name)?; 647 write!(f, "{}", name)?;
591 if substs.0.len() > 0 { 648 if substs.0.len() > 0 {
@@ -607,11 +664,11 @@ impl fmt::Display for Ty {
607 664
608/// Compute the declared type of a function. This should not need to look at the 665/// Compute the declared type of a function. This should not need to look at the
609/// function body. 666/// function body.
610fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty { 667fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
611 let signature = f.signature(db); 668 let signature = def.signature(db);
612 let module = f.module(db); 669 let module = def.module(db);
613 let impl_block = f.impl_block(db); 670 let impl_block = def.impl_block(db);
614 let generics = f.generic_params(db); 671 let generics = def.generic_params(db);
615 let input = signature 672 let input = signature
616 .params() 673 .params()
617 .iter() 674 .iter()
@@ -624,8 +681,15 @@ fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty {
624 &generics, 681 &generics,
625 signature.ret_type(), 682 signature.ret_type(),
626 ); 683 );
627 let sig = FnSig { input, output }; 684 let sig = Arc::new(FnSig { input, output });
628 Ty::FnPtr(Arc::new(sig)) 685 let substs = make_substs(&generics);
686 let name = def.name(db);
687 Ty::FnDef {
688 def,
689 sig,
690 name,
691 substs,
692 }
629} 693}
630 694
631fn make_substs(generics: &GenericParams) -> Substs { 695fn make_substs(generics: &GenericParams) -> Substs {
@@ -750,7 +814,7 @@ impl Index<PatId> for InferenceResult {
750struct InferenceContext<'a, D: HirDatabase> { 814struct InferenceContext<'a, D: HirDatabase> {
751 db: &'a D, 815 db: &'a D,
752 body: Arc<Body>, 816 body: Arc<Body>,
753 scopes: Arc<FnScopes>, 817 scopes: Arc<ExprScopes>,
754 module: Module, 818 module: Module,
755 impl_block: Option<ImplBlock>, 819 impl_block: Option<ImplBlock>,
756 var_unification_table: InPlaceUnificationTable<TypeVarId>, 820 var_unification_table: InPlaceUnificationTable<TypeVarId>,
@@ -844,7 +908,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
844 fn new( 908 fn new(
845 db: &'a D, 909 db: &'a D,
846 body: Arc<Body>, 910 body: Arc<Body>,
847 scopes: Arc<FnScopes>, 911 scopes: Arc<ExprScopes>,
848 module: Module, 912 module: Module,
849 impl_block: Option<ImplBlock>, 913 impl_block: Option<ImplBlock>,
850 ) -> Self { 914 ) -> Self {
@@ -1102,7 +1166,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1102 .into(); 1166 .into();
1103 let typable = typable?; 1167 let typable = typable?;
1104 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);
1105 let ty = self.insert_type_vars(ty); 1179 let ty = self.insert_type_vars(ty);
1180
1106 Some(ty) 1181 Some(ty)
1107 } 1182 }
1108 1183
@@ -1142,7 +1217,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1142 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1217 let ty = self.insert_type_vars(ty.apply_substs(substs));
1143 (ty, Some(var.into())) 1218 (ty, Some(var.into()))
1144 } 1219 }
1145 TypableDef::Enum(_) | TypableDef::Function(_) => (Ty::Unknown, None), 1220 TypableDef::Function(_) | TypableDef::Enum(_) => (Ty::Unknown, None),
1146 } 1221 }
1147 } 1222 }
1148 1223
@@ -1196,9 +1271,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1196 Ty::Tuple(ref tuple_args) => &**tuple_args, 1271 Ty::Tuple(ref tuple_args) => &**tuple_args,
1197 _ => &[], 1272 _ => &[],
1198 }; 1273 };
1199 let expectations_iter = expectations 1274 let expectations_iter = expectations.into_iter().chain(repeat(&Ty::Unknown));
1200 .into_iter()
1201 .chain(std::iter::repeat(&Ty::Unknown));
1202 1275
1203 let inner_tys = args 1276 let inner_tys = args
1204 .iter() 1277 .iter()
@@ -1332,18 +1405,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1332 Expr::Call { callee, args } => { 1405 Expr::Call { callee, args } => {
1333 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 1406 let callee_ty = self.infer_expr(*callee, &Expectation::none());
1334 let (param_tys, ret_ty) = match &callee_ty { 1407 let (param_tys, ret_ty) = match &callee_ty {
1335 Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), 1408 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
1409 Ty::FnDef { substs, sig, .. } => {
1410 let ret_ty = sig.output.clone().subst(&substs);
1411 let param_tys = sig
1412 .input
1413 .iter()
1414 .map(|ty| ty.clone().subst(&substs))
1415 .collect();
1416 (param_tys, ret_ty)
1417 }
1336 _ => { 1418 _ => {
1337 // not callable 1419 // not callable
1338 // TODO report an error? 1420 // TODO report an error?
1339 (&[][..], Ty::Unknown) 1421 (Vec::new(), Ty::Unknown)
1340 } 1422 }
1341 }; 1423 };
1342 for (i, arg) in args.iter().enumerate() { 1424 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
1343 self.infer_expr( 1425 for (arg, param) in args.iter().zip(param_iter) {
1344 *arg, 1426 self.infer_expr(*arg, &Expectation::has_type(param));
1345 &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)),
1346 );
1347 } 1427 }
1348 ret_ty 1428 ret_ty
1349 } 1429 }
@@ -1365,21 +1445,34 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1365 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { 1445 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
1366 Ty::FnPtr(sig) => { 1446 Ty::FnPtr(sig) => {
1367 if sig.input.len() > 0 { 1447 if sig.input.len() > 0 {
1368 (&sig.input[0], &sig.input[1..], sig.output.clone()) 1448 (
1449 sig.input[0].clone(),
1450 sig.input[1..].iter().cloned().collect(),
1451 sig.output.clone(),
1452 )
1453 } else {
1454 (Ty::Unknown, Vec::new(), sig.output.clone())
1455 }
1456 }
1457 Ty::FnDef { substs, sig, .. } => {
1458 let ret_ty = sig.output.clone().subst(&substs);
1459
1460 if sig.input.len() > 0 {
1461 let mut arg_iter = sig.input.iter().map(|ty| ty.clone().subst(&substs));
1462 let receiver_ty = arg_iter.next().unwrap();
1463 (receiver_ty, arg_iter.collect(), ret_ty)
1369 } else { 1464 } else {
1370 (&Ty::Unknown, &[][..], sig.output.clone()) 1465 (Ty::Unknown, Vec::new(), ret_ty)
1371 } 1466 }
1372 } 1467 }
1373 _ => (&Ty::Unknown, &[][..], Ty::Unknown), 1468 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
1374 }; 1469 };
1375 // TODO we would have to apply the autoderef/autoref steps here 1470 // TODO we would have to apply the autoderef/autoref steps here
1376 // to get the correct receiver type to unify... 1471 // to get the correct receiver type to unify...
1377 self.unify(expected_receiver_ty, &receiver_ty); 1472 self.unify(&expected_receiver_ty, &receiver_ty);
1378 for (i, arg) in args.iter().enumerate() { 1473 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
1379 self.infer_expr( 1474 for (arg, param) in args.iter().zip(param_iter) {
1380 *arg, 1475 self.infer_expr(*arg, &Expectation::has_type(param));
1381 &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)),
1382 );
1383 } 1476 }
1384 ret_ty 1477 ret_ty
1385 } 1478 }
@@ -1395,7 +1488,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1395 for &pat in &arm.pats { 1488 for &pat in &arm.pats {
1396 let _pat_ty = self.infer_pat(pat, &input_ty); 1489 let _pat_ty = self.infer_pat(pat, &input_ty);
1397 } 1490 }
1398 // TODO type the guard 1491 if let Some(guard_expr) = arm.guard {
1492 self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool));
1493 }
1399 self.infer_expr(arm.expr, &expected); 1494 self.infer_expr(arm.expr, &expected);
1400 } 1495 }
1401 1496
@@ -1468,9 +1563,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1468 cast_ty 1563 cast_ty
1469 } 1564 }
1470 Expr::Ref { expr, mutability } => { 1565 Expr::Ref { expr, mutability } => {
1471 // TODO pass the expectation down 1566 let expectation = if let Ty::Ref(ref subty, expected_mutability) = expected.ty {
1472 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 1567 if expected_mutability == Mutability::Mut && *mutability == Mutability::Shared {
1568 // TODO: throw type error - expected mut reference but found shared ref,
1569 // which cannot be coerced
1570 }
1571 Expectation::has_type((**subty).clone())
1572 } else {
1573 Expectation::none()
1574 };
1473 // TODO reference coercions etc. 1575 // TODO reference coercions etc.
1576 let inner_ty = self.infer_expr(*expr, &expectation);
1474 Ty::Ref(Arc::new(inner_ty), *mutability) 1577 Ty::Ref(Arc::new(inner_ty), *mutability)
1475 } 1578 }
1476 Expr::UnaryOp { expr, op } => { 1579 Expr::UnaryOp { expr, op } => {
@@ -1495,9 +1598,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1495 _ => Ty::Unknown, 1598 _ => Ty::Unknown,
1496 } 1599 }
1497 } 1600 }
1498 UnaryOp::Not if inner_ty == Ty::Bool => Ty::Bool, 1601 UnaryOp::Not => {
1499 // TODO: resolve ops::Not trait for inner_ty 1602 match inner_ty {
1500 UnaryOp::Not => Ty::Unknown, 1603 Ty::Bool | Ty::Int(_) | Ty::Infer(InferTy::IntVar(..)) => inner_ty,
1604 // TODO: resolve ops::Not trait for inner_ty
1605 _ => Ty::Unknown,
1606 }
1607 }
1501 } 1608 }
1502 } 1609 }
1503 Expr::BinaryOp { lhs, rhs, op } => match op { 1610 Expr::BinaryOp { lhs, rhs, op } => match op {
@@ -1609,10 +1716,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1609 1716
1610 self.infer_pat(*pat, &ty); 1717 self.infer_pat(*pat, &ty);
1611 } 1718 }
1612 self.return_ty = { 1719 self.return_ty = self.make_ty(signature.ret_type());
1613 let ty = self.make_ty(signature.ret_type());
1614 ty
1615 };
1616 } 1720 }
1617 1721
1618 fn infer_body(&mut self) { 1722 fn infer_body(&mut self) {
@@ -1626,7 +1730,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1626pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { 1730pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
1627 db.check_canceled(); 1731 db.check_canceled();
1628 let body = func.body(db); 1732 let body = func.body(db);
1629 let scopes = db.fn_scopes(func); 1733 let scopes = db.expr_scopes(func);
1630 let module = func.module(db); 1734 let module = func.module(db);
1631 let impl_block = func.impl_block(db); 1735 let impl_block = func.impl_block(db);
1632 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); 1736 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);