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.rs180
1 files changed, 101 insertions, 79 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 4c96579ee..f9cdbcab3 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -382,7 +382,8 @@ impl Ty {
382 382
383 // Resolve in module (in type namespace) 383 // Resolve in module (in type namespace)
384 let resolved = match module.resolve_path(db, path).take_types() { 384 let resolved = match module.resolve_path(db, path).take_types() {
385 Some(ModuleDef::Def(r)) => r, 385 Some(ModuleDef::Def(r)) => r.into(),
386 Some(ModuleDef::Function(f)) => f.into(),
386 None | Some(ModuleDef::Module(_)) => return Ty::Unknown, 387 None | Some(ModuleDef::Module(_)) => return Ty::Unknown,
387 }; 388 };
388 let ty = db.type_for_def(resolved); 389 let ty = db.type_for_def(resolved);
@@ -399,36 +400,38 @@ impl Ty {
399 impl_block: Option<&ImplBlock>, 400 impl_block: Option<&ImplBlock>,
400 outer_generics: &GenericParams, 401 outer_generics: &GenericParams,
401 path: &Path, 402 path: &Path,
402 resolved: DefId, 403 resolved: TypableDef,
403 ) -> Substs { 404 ) -> Substs {
404 let mut substs = Vec::new(); 405 let mut substs = Vec::new();
405 let def = resolved.resolve(db);
406 let last = path 406 let last = path
407 .segments 407 .segments
408 .last() 408 .last()
409 .expect("path should have at least one segment"); 409 .expect("path should have at least one segment");
410 let (def_generics, segment) = match def { 410 let (def_generics, segment) = match resolved {
411 Def::Struct(s) => (s.generic_params(db), last), 411 TypableDef::Function(func) => (func.generic_params(db), last),
412 Def::Enum(e) => (e.generic_params(db), last), 412 TypableDef::Def(def_id) => match def_id.resolve(db) {
413 Def::Function(f) => (f.generic_params(db), last), 413 Def::Struct(s) => (s.generic_params(db), last),
414 Def::Trait(t) => (t.generic_params(db), last), 414 Def::Enum(e) => (e.generic_params(db), last),
415 Def::EnumVariant(ev) => { 415 Def::Trait(t) => (t.generic_params(db), last),
416 // the generic args for an enum variant may be either specified 416 Def::EnumVariant(ev) => {
417 // on the segment referring to the enum, or on the segment 417 // the generic args for an enum variant may be either specified
418 // referring to the variant. So `Option::<T>::None` and 418 // on the segment referring to the enum, or on the segment
419 // `Option::None::<T>` are both allowed (though the former is 419 // referring to the variant. So `Option::<T>::None` and
420 // preferred). See also `def_ids_for_path_segments` in rustc. 420 // `Option::None::<T>` are both allowed (though the former is
421 let len = path.segments.len(); 421 // preferred). See also `def_ids_for_path_segments` in rustc.
422 let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some() { 422 let len = path.segments.len();
423 // Option::<T>::None 423 let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some()
424 &path.segments[len - 2] 424 {
425 } else { 425 // Option::<T>::None
426 // Option::None::<T> 426 &path.segments[len - 2]
427 last 427 } else {
428 }; 428 // Option::None::<T>
429 (ev.parent_enum(db).generic_params(db), segment) 429 last
430 } 430 };
431 _ => return Substs::empty(), 431 (ev.parent_enum(db).generic_params(db), segment)
432 }
433 _ => return Substs::empty(),
434 },
432 }; 435 };
433 // substs_from_path 436 // substs_from_path
434 if let Some(generic_args) = &segment.args_and_bindings { 437 if let Some(generic_args) = &segment.args_and_bindings {
@@ -660,21 +663,40 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T
660 type_for_enum(db, enum_parent) 663 type_for_enum(db, enum_parent)
661} 664}
662 665
663pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty { 666#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
664 let def = def_id.resolve(db); 667pub enum TypableDef {
668 Function(Function),
669 Def(DefId),
670}
671
672impl From<Function> for TypableDef {
673 fn from(func: Function) -> TypableDef {
674 TypableDef::Function(func)
675 }
676}
677
678impl From<DefId> for TypableDef {
679 fn from(func: DefId) -> TypableDef {
680 TypableDef::Def(func)
681 }
682}
683
684pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
665 match def { 685 match def {
666 Def::Function(f) => type_for_fn(db, f), 686 TypableDef::Function(f) => type_for_fn(db, f),
667 Def::Struct(s) => type_for_struct(db, s), 687 TypableDef::Def(def_id) => match def_id.resolve(db) {
668 Def::Enum(e) => type_for_enum(db, e), 688 Def::Struct(s) => type_for_struct(db, s),
669 Def::EnumVariant(ev) => type_for_enum_variant(db, ev), 689 Def::Enum(e) => type_for_enum(db, e),
670 _ => { 690 Def::EnumVariant(ev) => type_for_enum_variant(db, ev),
671 log::debug!( 691 _ => {
672 "trying to get type for item of unknown type {:?} {:?}", 692 log::debug!(
673 def_id, 693 "trying to get type for item of unknown type {:?} {:?}",
674 def 694 def_id,
675 ); 695 def
676 Ty::Unknown 696 );
677 } 697 Ty::Unknown
698 }
699 },
678 } 700 }
679} 701}
680 702
@@ -694,28 +716,23 @@ pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name)
694 ), 716 ),
695 }; 717 };
696 let module = def_id.module(db); 718 let module = def_id.module(db);
697 let impl_block = def_id.impl_block(db); 719 // We can't have an impl block ere, right?
720 // let impl_block = def_id.impl_block(db);
698 let type_ref = variant_data.get_field_type_ref(&field)?; 721 let type_ref = variant_data.get_field_type_ref(&field)?;
699 Some(Ty::from_hir( 722 Some(Ty::from_hir(db, &module, None, &generics, &type_ref))
700 db,
701 &module,
702 impl_block.as_ref(),
703 &generics,
704 &type_ref,
705 ))
706} 723}
707 724
708/// The result of type inference: A mapping from expressions and patterns to types. 725/// The result of type inference: A mapping from expressions and patterns to types.
709#[derive(Clone, PartialEq, Eq, Debug)] 726#[derive(Clone, PartialEq, Eq, Debug)]
710pub struct InferenceResult { 727pub struct InferenceResult {
711 /// For each method call expr, record the function it resolved to. 728 /// For each method call expr, record the function it resolved to.
712 method_resolutions: FxHashMap<ExprId, DefId>, 729 method_resolutions: FxHashMap<ExprId, Function>,
713 type_of_expr: ArenaMap<ExprId, Ty>, 730 type_of_expr: ArenaMap<ExprId, Ty>,
714 type_of_pat: ArenaMap<PatId, Ty>, 731 type_of_pat: ArenaMap<PatId, Ty>,
715} 732}
716 733
717impl InferenceResult { 734impl InferenceResult {
718 pub fn method_resolution(&self, expr: ExprId) -> Option<DefId> { 735 pub fn method_resolution(&self, expr: ExprId) -> Option<Function> {
719 self.method_resolutions.get(&expr).map(|it| *it) 736 self.method_resolutions.get(&expr).map(|it| *it)
720 } 737 }
721} 738}
@@ -745,7 +762,7 @@ struct InferenceContext<'a, D: HirDatabase> {
745 module: Module, 762 module: Module,
746 impl_block: Option<ImplBlock>, 763 impl_block: Option<ImplBlock>,
747 var_unification_table: InPlaceUnificationTable<TypeVarId>, 764 var_unification_table: InPlaceUnificationTable<TypeVarId>,
748 method_resolutions: FxHashMap<ExprId, DefId>, 765 method_resolutions: FxHashMap<ExprId, Function>,
749 type_of_expr: ArenaMap<ExprId, Ty>, 766 type_of_expr: ArenaMap<ExprId, Ty>,
750 type_of_pat: ArenaMap<PatId, Ty>, 767 type_of_pat: ArenaMap<PatId, Ty>,
751 /// The return type of the function being inferred. 768 /// The return type of the function being inferred.
@@ -871,8 +888,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
871 self.type_of_expr.insert(expr, ty); 888 self.type_of_expr.insert(expr, ty);
872 } 889 }
873 890
874 fn write_method_resolution(&mut self, expr: ExprId, def_id: DefId) { 891 fn write_method_resolution(&mut self, expr: ExprId, func: Function) {
875 self.method_resolutions.insert(expr, def_id); 892 self.method_resolutions.insert(expr, func);
876 } 893 }
877 894
878 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { 895 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
@@ -1060,7 +1077,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1060 1077
1061 // resolve in module 1078 // resolve in module
1062 let resolved = match self.module.resolve_path(self.db, &path).take_values()? { 1079 let resolved = match self.module.resolve_path(self.db, &path).take_values()? {
1063 ModuleDef::Def(it) => it, 1080 ModuleDef::Def(it) => it.into(),
1081 ModuleDef::Function(func) => func.into(),
1064 ModuleDef::Module(_) => return None, 1082 ModuleDef::Module(_) => return None,
1065 }; 1083 };
1066 let ty = self.db.type_for_def(resolved); 1084 let ty = self.db.type_for_def(resolved);
@@ -1073,8 +1091,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1073 Some(path) => path, 1091 Some(path) => path,
1074 None => return (Ty::Unknown, None), 1092 None => return (Ty::Unknown, None),
1075 }; 1093 };
1076 let def_id = match self.module.resolve_path(self.db, &path).take_types() { 1094 let def = match self.module.resolve_path(self.db, &path).take_types() {
1077 Some(ModuleDef::Def(def_id)) => def_id, 1095 Some(ModuleDef::Def(def_id)) => def_id.into(),
1096 Some(ModuleDef::Function(func)) => func.into(),
1078 _ => return (Ty::Unknown, None), 1097 _ => return (Ty::Unknown, None),
1079 }; 1098 };
1080 // TODO remove the duplication between here and `Ty::from_path`? 1099 // TODO remove the duplication between here and `Ty::from_path`?
@@ -1086,20 +1105,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1086 self.impl_block.as_ref(), 1105 self.impl_block.as_ref(),
1087 &generics, 1106 &generics,
1088 path, 1107 path,
1089 def_id, 1108 def,
1090 ); 1109 );
1091 match def_id.resolve(self.db) { 1110 match def {
1092 Def::Struct(s) => { 1111 TypableDef::Def(def_id) => match def_id.resolve(self.db) {
1093 let ty = type_for_struct(self.db, s); 1112 Def::Struct(s) => {
1094 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1113 let ty = type_for_struct(self.db, s);
1095 (ty, Some(def_id)) 1114 let ty = self.insert_type_vars(ty.apply_substs(substs));
1096 } 1115 (ty, Some(def_id))
1097 Def::EnumVariant(ev) => { 1116 }
1098 let ty = type_for_enum_variant(self.db, ev); 1117 Def::EnumVariant(ev) => {
1099 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1118 let ty = type_for_enum_variant(self.db, ev);
1100 (ty, Some(def_id)) 1119 let ty = self.insert_type_vars(ty.apply_substs(substs));
1101 } 1120 (ty, Some(def_id))
1102 _ => (Ty::Unknown, None), 1121 }
1122 _ => (Ty::Unknown, None),
1123 },
1124 TypableDef::Function(_) => (Ty::Unknown, None),
1103 } 1125 }
1104 } 1126 }
1105 1127
@@ -1216,7 +1238,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1216 .resolve_path(self.db, &path) 1238 .resolve_path(self.db, &path)
1217 .take_values() 1239 .take_values()
1218 .and_then(|module_def| match module_def { 1240 .and_then(|module_def| match module_def {
1219 ModuleDef::Def(it) => Some(it), 1241 ModuleDef::Def(it) => Some(it.into()),
1242 ModuleDef::Function(func) => Some(func.into()),
1220 ModuleDef::Module(_) => None, 1243 ModuleDef::Module(_) => None,
1221 }) 1244 })
1222 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), 1245 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)),
@@ -1339,9 +1362,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1339 let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); 1362 let receiver_ty = self.infer_expr(*receiver, &Expectation::none());
1340 let resolved = receiver_ty.clone().lookup_method(self.db, method_name); 1363 let resolved = receiver_ty.clone().lookup_method(self.db, method_name);
1341 let method_ty = match resolved { 1364 let method_ty = match resolved {
1342 Some(def_id) => { 1365 Some(func) => {
1343 self.write_method_resolution(expr, def_id); 1366 self.write_method_resolution(expr, func);
1344 self.db.type_for_def(def_id) 1367 self.db.type_for_def(func.into())
1345 } 1368 }
1346 None => Ty::Unknown, 1369 None => Ty::Unknown,
1347 }; 1370 };
@@ -1610,16 +1633,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1610 } 1633 }
1611} 1634}
1612 1635
1613pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Arc<InferenceResult> { 1636pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
1614 db.check_canceled(); 1637 db.check_canceled();
1615 let function = Function::new(def_id); // TODO: consts also need inference 1638 let body = func.body(db);
1616 let body = function.body(db); 1639 let scopes = db.fn_scopes(func);
1617 let scopes = db.fn_scopes(def_id); 1640 let module = func.module(db);
1618 let module = function.module(db); 1641 let impl_block = func.impl_block(db);
1619 let impl_block = function.impl_block(db);
1620 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); 1642 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);
1621 1643
1622 let signature = function.signature(db); 1644 let signature = func.signature(db);
1623 ctx.collect_fn_signature(&signature); 1645 ctx.collect_fn_signature(&signature);
1624 1646
1625 ctx.infer_body(); 1647 ctx.infer_body();