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.rs218
1 files changed, 117 insertions, 101 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index e690ae158..c7f77e7a3 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -24,15 +24,14 @@ use std::ops::Index;
24use std::sync::Arc; 24use std::sync::Arc;
25use std::{fmt, mem}; 25use std::{fmt, mem};
26 26
27use log;
28use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError}; 27use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError};
29use ra_arena::map::ArenaMap; 28use ra_arena::map::ArenaMap;
30use join_to_string::join; 29use join_to_string::join;
31use rustc_hash::FxHashMap; 30use rustc_hash::FxHashMap;
32 31
33use crate::{ 32use crate::{
34 Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, 33 Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
35 FnSignature, FnScopes, 34 FnSignature, FnScopes, ModuleDef, AdtDef,
36 db::HirDatabase, 35 db::HirDatabase,
37 type_ref::{TypeRef, Mutability}, 36 type_ref::{TypeRef, Mutability},
38 name::KnownName, 37 name::KnownName,
@@ -184,7 +183,7 @@ pub enum Ty {
184 /// Structures, enumerations and unions. 183 /// Structures, enumerations and unions.
185 Adt { 184 Adt {
186 /// The DefId of the struct/enum. 185 /// The DefId of the struct/enum.
187 def_id: DefId, 186 def_id: AdtDef,
188 /// The name, for displaying. 187 /// The name, for displaying.
189 name: Name, 188 name: Name,
190 /// Substitutions for the generic parameters of the type. 189 /// Substitutions for the generic parameters of the type.
@@ -381,12 +380,16 @@ impl Ty {
381 } 380 }
382 381
383 // Resolve in module (in type namespace) 382 // Resolve in module (in type namespace)
384 let resolved = match module.resolve_path(db, path).take_types() { 383 let typable: TypableDef = match module
385 Some(r) => r, 384 .resolve_path(db, path)
385 .take_types()
386 .and_then(|it| it.into())
387 {
386 None => return Ty::Unknown, 388 None => return Ty::Unknown,
389 Some(it) => it,
387 }; 390 };
388 let ty = db.type_for_def(resolved); 391 let ty = db.type_for_def(typable);
389 let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved); 392 let substs = Ty::substs_from_path(db, module, impl_block, generics, path, typable);
390 ty.apply_substs(substs) 393 ty.apply_substs(substs)
391 } 394 }
392 395
@@ -399,20 +402,18 @@ impl Ty {
399 impl_block: Option<&ImplBlock>, 402 impl_block: Option<&ImplBlock>,
400 outer_generics: &GenericParams, 403 outer_generics: &GenericParams,
401 path: &Path, 404 path: &Path,
402 resolved: DefId, 405 resolved: TypableDef,
403 ) -> Substs { 406 ) -> Substs {
404 let mut substs = Vec::new(); 407 let mut substs = Vec::new();
405 let def = resolved.resolve(db);
406 let last = path 408 let last = path
407 .segments 409 .segments
408 .last() 410 .last()
409 .expect("path should have at least one segment"); 411 .expect("path should have at least one segment");
410 let (def_generics, segment) = match def { 412 let (def_generics, segment) = match resolved {
411 Def::Struct(s) => (s.generic_params(db), last), 413 TypableDef::Function(func) => (func.generic_params(db), last),
412 Def::Enum(e) => (e.generic_params(db), last), 414 TypableDef::Struct(s) => (s.generic_params(db), last),
413 Def::Function(f) => (f.generic_params(db), last), 415 TypableDef::Enum(e) => (e.generic_params(db), last),
414 Def::Trait(t) => (t.generic_params(db), last), 416 TypableDef::EnumVariant(var) => {
415 Def::EnumVariant(ev) => {
416 // the generic args for an enum variant may be either specified 417 // the generic args for an enum variant may be either specified
417 // on the segment referring to the enum, or on the segment 418 // on the segment referring to the enum, or on the segment
418 // referring to the variant. So `Option::<T>::None` and 419 // referring to the variant. So `Option::<T>::None` and
@@ -426,9 +427,8 @@ impl Ty {
426 // Option::None::<T> 427 // Option::None::<T>
427 last 428 last
428 }; 429 };
429 (ev.parent_enum(db).generic_params(db), segment) 430 (var.parent_enum(db).generic_params(db), segment)
430 } 431 }
431 _ => return Substs::empty(),
432 }; 432 };
433 // substs_from_path 433 // substs_from_path
434 if let Some(generic_args) = &segment.args_and_bindings { 434 if let Some(generic_args) = &segment.args_and_bindings {
@@ -639,7 +639,7 @@ fn make_substs(generics: &GenericParams) -> Substs {
639fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { 639fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
640 let generics = s.generic_params(db); 640 let generics = s.generic_params(db);
641 Ty::Adt { 641 Ty::Adt {
642 def_id: s.def_id(), 642 def_id: s.into(),
643 name: s.name(db).unwrap_or_else(Name::missing), 643 name: s.name(db).unwrap_or_else(Name::missing),
644 substs: make_substs(&generics), 644 substs: make_substs(&generics),
645 } 645 }
@@ -648,7 +648,7 @@ fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
648pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { 648pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
649 let generics = s.generic_params(db); 649 let generics = s.generic_params(db);
650 Ty::Adt { 650 Ty::Adt {
651 def_id: s.def_id(), 651 def_id: s.into(),
652 name: s.name(db).unwrap_or_else(Name::missing), 652 name: s.name(db).unwrap_or_else(Name::missing),
653 substs: make_substs(&generics), 653 substs: make_substs(&generics),
654 } 654 }
@@ -660,66 +660,74 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T
660 type_for_enum(db, enum_parent) 660 type_for_enum(db, enum_parent)
661} 661}
662 662
663pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty { 663#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
664 let def = def_id.resolve(db); 664pub enum TypableDef {
665 Function(Function),
666 Struct(Struct),
667 Enum(Enum),
668 EnumVariant(EnumVariant),
669}
670impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant);
671
672impl From<ModuleDef> for Option<TypableDef> {
673 fn from(def: ModuleDef) -> Option<TypableDef> {
674 let res = match def {
675 ModuleDef::Function(f) => f.into(),
676 ModuleDef::Struct(s) => s.into(),
677 ModuleDef::Enum(e) => e.into(),
678 ModuleDef::EnumVariant(v) => v.into(),
679 ModuleDef::Const(_)
680 | ModuleDef::Static(_)
681 | ModuleDef::Module(_)
682 | ModuleDef::Trait(_)
683 | ModuleDef::Type(_) => return None,
684 };
685 Some(res)
686 }
687}
688
689pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
665 match def { 690 match def {
666 Def::Module(..) => { 691 TypableDef::Function(f) => type_for_fn(db, f),
667 log::debug!("trying to get type for module {:?}", def_id); 692 TypableDef::Struct(s) => type_for_struct(db, s),
668 Ty::Unknown 693 TypableDef::Enum(e) => type_for_enum(db, e),
669 } 694 TypableDef::EnumVariant(v) => type_for_enum_variant(db, v),
670 Def::Function(f) => type_for_fn(db, f),
671 Def::Struct(s) => type_for_struct(db, s),
672 Def::Enum(e) => type_for_enum(db, e),
673 Def::EnumVariant(ev) => type_for_enum_variant(db, ev),
674 _ => {
675 log::debug!(
676 "trying to get type for item of unknown type {:?} {:?}",
677 def_id,
678 def
679 );
680 Ty::Unknown
681 }
682 } 695 }
683} 696}
684 697
685pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> { 698#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
686 let def = def_id.resolve(db); 699pub enum VariantDef {
687 let (variant_data, generics) = match def { 700 Struct(Struct),
688 Def::Struct(s) => (s.variant_data(db), s.generic_params(db)), 701 EnumVariant(EnumVariant),
689 Def::EnumVariant(ev) => (ev.variant_data(db), ev.parent_enum(db).generic_params(db)), 702}
690 // TODO: unions 703impl_froms!(VariantDef: Struct, EnumVariant);
691 Def::Enum(_) => { 704
692 // this can happen in (invalid) code, but enums don't have fields themselves 705pub(super) fn type_for_field(db: &impl HirDatabase, def: VariantDef, field: Name) -> Option<Ty> {
693 return None; 706 let (variant_data, generics, module) = match def {
694 } 707 VariantDef::Struct(s) => (s.variant_data(db), s.generic_params(db), s.module(db)),
695 _ => panic!( 708 VariantDef::EnumVariant(var) => (
696 "trying to get type for field {:?} in non-struct/variant {:?}", 709 var.variant_data(db),
697 field, def_id 710 var.parent_enum(db).generic_params(db),
711 var.module(db),
698 ), 712 ),
699 }; 713 };
700 let module = def_id.module(db); 714 // We can't have an impl block ere, right?
701 let impl_block = def_id.impl_block(db); 715 // let impl_block = def_id.impl_block(db);
702 let type_ref = variant_data.get_field_type_ref(&field)?; 716 let type_ref = variant_data.get_field_type_ref(&field)?;
703 Some(Ty::from_hir( 717 Some(Ty::from_hir(db, &module, None, &generics, &type_ref))
704 db,
705 &module,
706 impl_block.as_ref(),
707 &generics,
708 &type_ref,
709 ))
710} 718}
711 719
712/// The result of type inference: A mapping from expressions and patterns to types. 720/// The result of type inference: A mapping from expressions and patterns to types.
713#[derive(Clone, PartialEq, Eq, Debug)] 721#[derive(Clone, PartialEq, Eq, Debug)]
714pub struct InferenceResult { 722pub struct InferenceResult {
715 /// For each method call expr, record the function it resolved to. 723 /// For each method call expr, record the function it resolved to.
716 method_resolutions: FxHashMap<ExprId, DefId>, 724 method_resolutions: FxHashMap<ExprId, Function>,
717 type_of_expr: ArenaMap<ExprId, Ty>, 725 type_of_expr: ArenaMap<ExprId, Ty>,
718 type_of_pat: ArenaMap<PatId, Ty>, 726 type_of_pat: ArenaMap<PatId, Ty>,
719} 727}
720 728
721impl InferenceResult { 729impl InferenceResult {
722 pub fn method_resolution(&self, expr: ExprId) -> Option<DefId> { 730 pub fn method_resolution(&self, expr: ExprId) -> Option<Function> {
723 self.method_resolutions.get(&expr).map(|it| *it) 731 self.method_resolutions.get(&expr).map(|it| *it)
724 } 732 }
725} 733}
@@ -749,7 +757,7 @@ struct InferenceContext<'a, D: HirDatabase> {
749 module: Module, 757 module: Module,
750 impl_block: Option<ImplBlock>, 758 impl_block: Option<ImplBlock>,
751 var_unification_table: InPlaceUnificationTable<TypeVarId>, 759 var_unification_table: InPlaceUnificationTable<TypeVarId>,
752 method_resolutions: FxHashMap<ExprId, DefId>, 760 method_resolutions: FxHashMap<ExprId, Function>,
753 type_of_expr: ArenaMap<ExprId, Ty>, 761 type_of_expr: ArenaMap<ExprId, Ty>,
754 type_of_pat: ArenaMap<PatId, Ty>, 762 type_of_pat: ArenaMap<PatId, Ty>,
755 /// The return type of the function being inferred. 763 /// The return type of the function being inferred.
@@ -875,8 +883,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
875 self.type_of_expr.insert(expr, ty); 883 self.type_of_expr.insert(expr, ty);
876 } 884 }
877 885
878 fn write_method_resolution(&mut self, expr: ExprId, def_id: DefId) { 886 fn write_method_resolution(&mut self, expr: ExprId, func: Function) {
879 self.method_resolutions.insert(expr, def_id); 887 self.method_resolutions.insert(expr, func);
880 } 888 }
881 889
882 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { 890 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
@@ -1063,20 +1071,30 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1063 }; 1071 };
1064 1072
1065 // resolve in module 1073 // resolve in module
1066 let resolved = self.module.resolve_path(self.db, &path).take_values()?; 1074 let typable: Option<TypableDef> = self
1067 let ty = self.db.type_for_def(resolved); 1075 .module
1076 .resolve_path(self.db, &path)
1077 .take_values()?
1078 .into();
1079 let typable = typable?;
1080 let ty = self.db.type_for_def(typable);
1068 let ty = self.insert_type_vars(ty); 1081 let ty = self.insert_type_vars(ty);
1069 Some(ty) 1082 Some(ty)
1070 } 1083 }
1071 1084
1072 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<DefId>) { 1085 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) {
1073 let path = match path { 1086 let path = match path {
1074 Some(path) => path, 1087 Some(path) => path,
1075 None => return (Ty::Unknown, None), 1088 None => return (Ty::Unknown, None),
1076 }; 1089 };
1077 let def_id = match self.module.resolve_path(self.db, &path).take_types() { 1090 let typable: Option<TypableDef> = self
1078 Some(def_id) => def_id, 1091 .module
1079 _ => return (Ty::Unknown, None), 1092 .resolve_path(self.db, &path)
1093 .take_types()
1094 .and_then(|it| it.into());
1095 let def = match typable {
1096 None => return (Ty::Unknown, None),
1097 Some(it) => it,
1080 }; 1098 };
1081 // TODO remove the duplication between here and `Ty::from_path`? 1099 // TODO remove the duplication between here and `Ty::from_path`?
1082 // TODO provide generics of function 1100 // TODO provide generics of function
@@ -1087,38 +1105,34 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1087 self.impl_block.as_ref(), 1105 self.impl_block.as_ref(),
1088 &generics, 1106 &generics,
1089 path, 1107 path,
1090 def_id, 1108 def,
1091 ); 1109 );
1092 match def_id.resolve(self.db) { 1110 match def {
1093 Def::Struct(s) => { 1111 TypableDef::Struct(s) => {
1094 let ty = type_for_struct(self.db, s); 1112 let ty = type_for_struct(self.db, s);
1095 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1113 let ty = self.insert_type_vars(ty.apply_substs(substs));
1096 (ty, Some(def_id)) 1114 (ty, Some(s.into()))
1097 } 1115 }
1098 Def::EnumVariant(ev) => { 1116 TypableDef::EnumVariant(var) => {
1099 let ty = type_for_enum_variant(self.db, ev); 1117 let ty = type_for_enum_variant(self.db, var);
1100 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1118 let ty = self.insert_type_vars(ty.apply_substs(substs));
1101 (ty, Some(def_id)) 1119 (ty, Some(var.into()))
1102 } 1120 }
1103 _ => (Ty::Unknown, None), 1121 TypableDef::Enum(_) | TypableDef::Function(_) => (Ty::Unknown, None),
1104 } 1122 }
1105 } 1123 }
1106 1124
1107 fn resolve_fields(&mut self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> { 1125 fn resolve_fields(&mut self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> {
1108 let (ty, def_id) = self.resolve_variant(path); 1126 let (ty, def) = self.resolve_variant(path);
1109 let def_id = def_id?; 1127 match def? {
1110 let def = def_id.resolve(self.db); 1128 VariantDef::Struct(s) => {
1111
1112 match def {
1113 Def::Struct(s) => {
1114 let fields = s.fields(self.db); 1129 let fields = s.fields(self.db);
1115 Some((ty, fields)) 1130 Some((ty, fields))
1116 } 1131 }
1117 Def::EnumVariant(ev) => { 1132 VariantDef::EnumVariant(var) => {
1118 let fields = ev.fields(self.db); 1133 let fields = var.fields(self.db);
1119 Some((ty, fields)) 1134 Some((ty, fields))
1120 } 1135 }
1121 _ => None,
1122 } 1136 }
1123 } 1137 }
1124 1138
@@ -1216,6 +1230,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1216 .module 1230 .module
1217 .resolve_path(self.db, &path) 1231 .resolve_path(self.db, &path)
1218 .take_values() 1232 .take_values()
1233 .and_then(|module_def| module_def.into())
1219 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), 1234 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)),
1220 Pat::Bind { 1235 Pat::Bind {
1221 mode, 1236 mode,
@@ -1336,9 +1351,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1336 let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); 1351 let receiver_ty = self.infer_expr(*receiver, &Expectation::none());
1337 let resolved = receiver_ty.clone().lookup_method(self.db, method_name); 1352 let resolved = receiver_ty.clone().lookup_method(self.db, method_name);
1338 let method_ty = match resolved { 1353 let method_ty = match resolved {
1339 Some(def_id) => { 1354 Some(func) => {
1340 self.write_method_resolution(expr, def_id); 1355 self.write_method_resolution(expr, func);
1341 self.db.type_for_def(def_id) 1356 self.db.type_for_def(func.into())
1342 } 1357 }
1343 None => Ty::Unknown, 1358 None => Ty::Unknown,
1344 }; 1359 };
@@ -1407,7 +1422,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1407 for field in fields { 1422 for field in fields {
1408 let field_ty = if let Some(def_id) = def_id { 1423 let field_ty = if let Some(def_id) = def_id {
1409 self.db 1424 self.db
1410 .type_for_field(def_id, field.name.clone()) 1425 .type_for_field(def_id.into(), field.name.clone())
1411 .unwrap_or(Ty::Unknown) 1426 .unwrap_or(Ty::Unknown)
1412 .subst(&substs) 1427 .subst(&substs)
1413 } else { 1428 } else {
@@ -1431,10 +1446,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1431 i.and_then(|i| fields.get(i).cloned()) 1446 i.and_then(|i| fields.get(i).cloned())
1432 } 1447 }
1433 Ty::Adt { 1448 Ty::Adt {
1434 def_id, ref substs, .. 1449 def_id: AdtDef::Struct(s),
1450 ref substs,
1451 ..
1435 } => self 1452 } => self
1436 .db 1453 .db
1437 .type_for_field(def_id, name.clone()) 1454 .type_for_field(s.into(), name.clone())
1438 .map(|ty| ty.subst(substs)), 1455 .map(|ty| ty.subst(substs)),
1439 _ => None, 1456 _ => None,
1440 }) 1457 })
@@ -1607,16 +1624,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1607 } 1624 }
1608} 1625}
1609 1626
1610pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Arc<InferenceResult> { 1627pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
1611 db.check_canceled(); 1628 db.check_canceled();
1612 let function = Function::new(def_id); // TODO: consts also need inference 1629 let body = func.body(db);
1613 let body = function.body(db); 1630 let scopes = db.fn_scopes(func);
1614 let scopes = db.fn_scopes(def_id); 1631 let module = func.module(db);
1615 let module = function.module(db); 1632 let impl_block = func.impl_block(db);
1616 let impl_block = function.impl_block(db);
1617 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); 1633 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);
1618 1634
1619 let signature = function.signature(db); 1635 let signature = func.signature(db);
1620 ctx.collect_fn_signature(&signature); 1636 ctx.collect_fn_signature(&signature);
1621 1637
1622 ctx.infer_body(); 1638 ctx.infer_body();