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.rs150
1 files changed, 106 insertions, 44 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index f9cdbcab3..fc699a2ae 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -32,7 +32,7 @@ use rustc_hash::FxHashMap;
32 32
33use crate::{ 33use crate::{
34 Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, 34 Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
35 FnSignature, FnScopes, ModuleDef, 35 FnSignature, FnScopes, ModuleDef, Crate,
36 db::HirDatabase, 36 db::HirDatabase,
37 type_ref::{TypeRef, Mutability}, 37 type_ref::{TypeRef, Mutability},
38 name::KnownName, 38 name::KnownName,
@@ -163,6 +163,33 @@ impl Substs {
163 } 163 }
164} 164}
165 165
166#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
167pub enum AdtDef {
168 Struct(Struct),
169 Def(DefId), // Enum
170}
171
172impl From<Struct> for AdtDef {
173 fn from(struct_: Struct) -> AdtDef {
174 AdtDef::Struct(struct_)
175 }
176}
177
178impl From<DefId> for AdtDef {
179 fn from(def_id: DefId) -> AdtDef {
180 AdtDef::Def(def_id)
181 }
182}
183
184impl AdtDef {
185 fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
186 match self {
187 AdtDef::Struct(s) => s.module(db).krate(db),
188 AdtDef::Def(def_id) => def_id.krate(db),
189 }
190 }
191}
192
166/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs). 193/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs).
167/// 194///
168/// This should be cheap to clone. 195/// This should be cheap to clone.
@@ -184,7 +211,7 @@ pub enum Ty {
184 /// Structures, enumerations and unions. 211 /// Structures, enumerations and unions.
185 Adt { 212 Adt {
186 /// The DefId of the struct/enum. 213 /// The DefId of the struct/enum.
187 def_id: DefId, 214 def_id: AdtDef,
188 /// The name, for displaying. 215 /// The name, for displaying.
189 name: Name, 216 name: Name,
190 /// Substitutions for the generic parameters of the type. 217 /// Substitutions for the generic parameters of the type.
@@ -384,6 +411,7 @@ impl Ty {
384 let resolved = match module.resolve_path(db, path).take_types() { 411 let resolved = match module.resolve_path(db, path).take_types() {
385 Some(ModuleDef::Def(r)) => r.into(), 412 Some(ModuleDef::Def(r)) => r.into(),
386 Some(ModuleDef::Function(f)) => f.into(), 413 Some(ModuleDef::Function(f)) => f.into(),
414 Some(ModuleDef::Struct(s)) => s.into(),
387 None | Some(ModuleDef::Module(_)) => return Ty::Unknown, 415 None | Some(ModuleDef::Module(_)) => return Ty::Unknown,
388 }; 416 };
389 let ty = db.type_for_def(resolved); 417 let ty = db.type_for_def(resolved);
@@ -409,6 +437,7 @@ impl Ty {
409 .expect("path should have at least one segment"); 437 .expect("path should have at least one segment");
410 let (def_generics, segment) = match resolved { 438 let (def_generics, segment) = match resolved {
411 TypableDef::Function(func) => (func.generic_params(db), last), 439 TypableDef::Function(func) => (func.generic_params(db), last),
440 TypableDef::Struct(s) => (s.generic_params(db), last),
412 TypableDef::Def(def_id) => match def_id.resolve(db) { 441 TypableDef::Def(def_id) => match def_id.resolve(db) {
413 Def::Struct(s) => (s.generic_params(db), last), 442 Def::Struct(s) => (s.generic_params(db), last),
414 Def::Enum(e) => (e.generic_params(db), last), 443 Def::Enum(e) => (e.generic_params(db), last),
@@ -642,7 +671,7 @@ fn make_substs(generics: &GenericParams) -> Substs {
642fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { 671fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
643 let generics = s.generic_params(db); 672 let generics = s.generic_params(db);
644 Ty::Adt { 673 Ty::Adt {
645 def_id: s.def_id(), 674 def_id: s.into(),
646 name: s.name(db).unwrap_or_else(Name::missing), 675 name: s.name(db).unwrap_or_else(Name::missing),
647 substs: make_substs(&generics), 676 substs: make_substs(&generics),
648 } 677 }
@@ -651,7 +680,7 @@ fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
651pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { 680pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
652 let generics = s.generic_params(db); 681 let generics = s.generic_params(db);
653 Ty::Adt { 682 Ty::Adt {
654 def_id: s.def_id(), 683 def_id: s.def_id().into(),
655 name: s.name(db).unwrap_or_else(Name::missing), 684 name: s.name(db).unwrap_or_else(Name::missing),
656 substs: make_substs(&generics), 685 substs: make_substs(&generics),
657 } 686 }
@@ -666,6 +695,7 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T
666#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 695#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
667pub enum TypableDef { 696pub enum TypableDef {
668 Function(Function), 697 Function(Function),
698 Struct(Struct),
669 Def(DefId), 699 Def(DefId),
670} 700}
671 701
@@ -675,6 +705,12 @@ impl From<Function> for TypableDef {
675 } 705 }
676} 706}
677 707
708impl From<Struct> for TypableDef {
709 fn from(struct_: Struct) -> TypableDef {
710 TypableDef::Struct(struct_)
711 }
712}
713
678impl From<DefId> for TypableDef { 714impl From<DefId> for TypableDef {
679 fn from(func: DefId) -> TypableDef { 715 fn from(func: DefId) -> TypableDef {
680 TypableDef::Def(func) 716 TypableDef::Def(func)
@@ -684,8 +720,8 @@ impl From<DefId> for TypableDef {
684pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { 720pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
685 match def { 721 match def {
686 TypableDef::Function(f) => type_for_fn(db, f), 722 TypableDef::Function(f) => type_for_fn(db, f),
723 TypableDef::Struct(s) => type_for_struct(db, s),
687 TypableDef::Def(def_id) => match def_id.resolve(db) { 724 TypableDef::Def(def_id) => match def_id.resolve(db) {
688 Def::Struct(s) => type_for_struct(db, s),
689 Def::Enum(e) => type_for_enum(db, e), 725 Def::Enum(e) => type_for_enum(db, e),
690 Def::EnumVariant(ev) => type_for_enum_variant(db, ev), 726 Def::EnumVariant(ev) => type_for_enum_variant(db, ev),
691 _ => { 727 _ => {
@@ -700,22 +736,44 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
700 } 736 }
701} 737}
702 738
703pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> { 739#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
704 let def = def_id.resolve(db); 740pub enum VariantDef {
705 let (variant_data, generics) = match def { 741 Struct(Struct),
706 Def::Struct(s) => (s.variant_data(db), s.generic_params(db)), 742 Def(DefId), // EnumVariant
707 Def::EnumVariant(ev) => (ev.variant_data(db), ev.parent_enum(db).generic_params(db)), 743}
708 // TODO: unions 744
709 Def::Enum(_) => { 745impl From<Struct> for VariantDef {
710 // this can happen in (invalid) code, but enums don't have fields themselves 746 fn from(struct_: Struct) -> VariantDef {
711 return None; 747 VariantDef::Struct(struct_)
712 } 748 }
713 _ => panic!( 749}
714 "trying to get type for field {:?} in non-struct/variant {:?}", 750
715 field, def_id 751impl From<DefId> for VariantDef {
716 ), 752 fn from(def_id: DefId) -> VariantDef {
753 VariantDef::Def(def_id)
754 }
755}
756
757pub(super) fn type_for_field(db: &impl HirDatabase, def: VariantDef, field: Name) -> Option<Ty> {
758 let (variant_data, generics, module) = match def {
759 VariantDef::Struct(s) => (s.variant_data(db), s.generic_params(db), s.module(db)),
760 VariantDef::Def(def_id) => match def_id.resolve(db) {
761 Def::EnumVariant(ev) => (
762 ev.variant_data(db),
763 ev.parent_enum(db).generic_params(db),
764 def_id.module(db),
765 ),
766 // TODO: unions
767 Def::Enum(_) => {
768 // this can happen in (invalid) code, but enums don't have fields themselves
769 return None;
770 }
771 _ => panic!(
772 "trying to get type for field {:?} in non-struct/variant {:?}",
773 field, def_id
774 ),
775 },
717 }; 776 };
718 let module = def_id.module(db);
719 // We can't have an impl block ere, right? 777 // We can't have an impl block ere, right?
720 // let impl_block = def_id.impl_block(db); 778 // let impl_block = def_id.impl_block(db);
721 let type_ref = variant_data.get_field_type_ref(&field)?; 779 let type_ref = variant_data.get_field_type_ref(&field)?;
@@ -1076,17 +1134,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1076 }; 1134 };
1077 1135
1078 // resolve in module 1136 // resolve in module
1079 let resolved = match self.module.resolve_path(self.db, &path).take_values()? { 1137 let typable = match self.module.resolve_path(self.db, &path).take_values()? {
1080 ModuleDef::Def(it) => it.into(), 1138 ModuleDef::Def(it) => it.into(),
1081 ModuleDef::Function(func) => func.into(), 1139 ModuleDef::Function(func) => func.into(),
1140 ModuleDef::Struct(s) => s.into(),
1082 ModuleDef::Module(_) => return None, 1141 ModuleDef::Module(_) => return None,
1083 }; 1142 };
1084 let ty = self.db.type_for_def(resolved); 1143 let ty = self.db.type_for_def(typable);
1085 let ty = self.insert_type_vars(ty); 1144 let ty = self.insert_type_vars(ty);
1086 Some(ty) 1145 Some(ty)
1087 } 1146 }
1088 1147
1089 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<DefId>) { 1148 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) {
1090 let path = match path { 1149 let path = match path {
1091 Some(path) => path, 1150 Some(path) => path,
1092 None => return (Ty::Unknown, None), 1151 None => return (Ty::Unknown, None),
@@ -1094,7 +1153,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1094 let def = match self.module.resolve_path(self.db, &path).take_types() { 1153 let def = match self.module.resolve_path(self.db, &path).take_types() {
1095 Some(ModuleDef::Def(def_id)) => def_id.into(), 1154 Some(ModuleDef::Def(def_id)) => def_id.into(),
1096 Some(ModuleDef::Function(func)) => func.into(), 1155 Some(ModuleDef::Function(func)) => func.into(),
1097 _ => return (Ty::Unknown, None), 1156 Some(ModuleDef::Struct(s)) => s.into(),
1157 None | Some(ModuleDef::Module(_)) => return (Ty::Unknown, None),
1098 }; 1158 };
1099 // TODO remove the duplication between here and `Ty::from_path`? 1159 // TODO remove the duplication between here and `Ty::from_path`?
1100 // TODO provide generics of function 1160 // TODO provide generics of function
@@ -1109,37 +1169,36 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1109 ); 1169 );
1110 match def { 1170 match def {
1111 TypableDef::Def(def_id) => match def_id.resolve(self.db) { 1171 TypableDef::Def(def_id) => match def_id.resolve(self.db) {
1112 Def::Struct(s) => {
1113 let ty = type_for_struct(self.db, s);
1114 let ty = self.insert_type_vars(ty.apply_substs(substs));
1115 (ty, Some(def_id))
1116 }
1117 Def::EnumVariant(ev) => { 1172 Def::EnumVariant(ev) => {
1118 let ty = type_for_enum_variant(self.db, ev); 1173 let ty = type_for_enum_variant(self.db, ev);
1119 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1174 let ty = self.insert_type_vars(ty.apply_substs(substs));
1120 (ty, Some(def_id)) 1175 (ty, Some(def_id.into()))
1121 } 1176 }
1122 _ => (Ty::Unknown, None), 1177 _ => (Ty::Unknown, None),
1123 }, 1178 },
1124 TypableDef::Function(_) => (Ty::Unknown, None), 1179 TypableDef::Function(_) => (Ty::Unknown, None),
1180 TypableDef::Struct(s) => {
1181 let ty = type_for_struct(self.db, s);
1182 let ty = self.insert_type_vars(ty.apply_substs(substs));
1183 (ty, Some(s.into()))
1184 }
1125 } 1185 }
1126 } 1186 }
1127 1187
1128 fn resolve_fields(&mut self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> { 1188 fn resolve_fields(&mut self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> {
1129 let (ty, def_id) = self.resolve_variant(path); 1189 let (ty, def) = self.resolve_variant(path);
1130 let def_id = def_id?; 1190 match def? {
1131 let def = def_id.resolve(self.db); 1191 VariantDef::Struct(s) => {
1132
1133 match def {
1134 Def::Struct(s) => {
1135 let fields = s.fields(self.db); 1192 let fields = s.fields(self.db);
1136 Some((ty, fields)) 1193 Some((ty, fields))
1137 } 1194 }
1138 Def::EnumVariant(ev) => { 1195 VariantDef::Def(def_id) => match def_id.resolve(self.db) {
1139 let fields = ev.fields(self.db); 1196 Def::EnumVariant(ev) => {
1140 Some((ty, fields)) 1197 let fields = ev.fields(self.db);
1141 } 1198 Some((ty, fields))
1142 _ => None, 1199 }
1200 _ => None,
1201 },
1143 } 1202 }
1144 } 1203 }
1145 1204
@@ -1240,6 +1299,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1240 .and_then(|module_def| match module_def { 1299 .and_then(|module_def| match module_def {
1241 ModuleDef::Def(it) => Some(it.into()), 1300 ModuleDef::Def(it) => Some(it.into()),
1242 ModuleDef::Function(func) => Some(func.into()), 1301 ModuleDef::Function(func) => Some(func.into()),
1302 ModuleDef::Struct(s) => Some(s.into()),
1243 ModuleDef::Module(_) => None, 1303 ModuleDef::Module(_) => None,
1244 }) 1304 })
1245 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), 1305 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)),
@@ -1433,7 +1493,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1433 for field in fields { 1493 for field in fields {
1434 let field_ty = if let Some(def_id) = def_id { 1494 let field_ty = if let Some(def_id) = def_id {
1435 self.db 1495 self.db
1436 .type_for_field(def_id, field.name.clone()) 1496 .type_for_field(def_id.into(), field.name.clone())
1437 .unwrap_or(Ty::Unknown) 1497 .unwrap_or(Ty::Unknown)
1438 .subst(&substs) 1498 .subst(&substs)
1439 } else { 1499 } else {
@@ -1457,10 +1517,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1457 i.and_then(|i| fields.get(i).cloned()) 1517 i.and_then(|i| fields.get(i).cloned())
1458 } 1518 }
1459 Ty::Adt { 1519 Ty::Adt {
1460 def_id, ref substs, .. 1520 def_id: AdtDef::Struct(s),
1521 ref substs,
1522 ..
1461 } => self 1523 } => self
1462 .db 1524 .db
1463 .type_for_field(def_id, name.clone()) 1525 .type_for_field(s.into(), name.clone())
1464 .map(|ty| ty.subst(substs)), 1526 .map(|ty| ty.subst(substs)),
1465 _ => None, 1527 _ => None,
1466 }) 1528 })