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.rs121
1 files changed, 48 insertions, 73 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index fcf8a1dbb..66cf2bd64 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -431,25 +431,24 @@ impl Ty {
431 TypableDef::Function(func) => (func.generic_params(db), last), 431 TypableDef::Function(func) => (func.generic_params(db), last),
432 TypableDef::Struct(s) => (s.generic_params(db), last), 432 TypableDef::Struct(s) => (s.generic_params(db), last),
433 TypableDef::Enum(e) => (e.generic_params(db), last), 433 TypableDef::Enum(e) => (e.generic_params(db), last),
434 TypableDef::EnumVariant(var) => {
435 // the generic args for an enum variant may be either specified
436 // on the segment referring to the enum, or on the segment
437 // referring to the variant. So `Option::<T>::None` and
438 // `Option::None::<T>` are both allowed (though the former is
439 // preferred). See also `def_ids_for_path_segments` in rustc.
440 let len = path.segments.len();
441 let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some() {
442 // Option::<T>::None
443 &path.segments[len - 2]
444 } else {
445 // Option::None::<T>
446 last
447 };
448 (var.parent_enum(db).generic_params(db), segment)
449 }
434 TypableDef::Def(def_id) => match def_id.resolve(db) { 450 TypableDef::Def(def_id) => match def_id.resolve(db) {
435 Def::Trait(t) => (t.generic_params(db), last), 451 Def::Trait(t) => (t.generic_params(db), last),
436 Def::EnumVariant(ev) => {
437 // the generic args for an enum variant may be either specified
438 // on the segment referring to the enum, or on the segment
439 // referring to the variant. So `Option::<T>::None` and
440 // `Option::None::<T>` are both allowed (though the former is
441 // preferred). See also `def_ids_for_path_segments` in rustc.
442 let len = path.segments.len();
443 let segment = if len >= 2 && path.segments[len - 2].args_and_bindings.is_some()
444 {
445 // Option::<T>::None
446 &path.segments[len - 2]
447 } else {
448 // Option::None::<T>
449 last
450 };
451 (ev.parent_enum(db).generic_params(db), segment)
452 }
453 _ => return Substs::empty(), 452 _ => return Substs::empty(),
454 }, 453 },
455 }; 454 };
@@ -688,9 +687,10 @@ pub enum TypableDef {
688 Function(Function), 687 Function(Function),
689 Struct(Struct), 688 Struct(Struct),
690 Enum(Enum), 689 Enum(Enum),
690 EnumVariant(EnumVariant),
691 Def(DefId), 691 Def(DefId),
692} 692}
693impl_froms!(TypableDef: Function, Struct, Enum); 693impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant);
694 694
695impl From<DefId> for TypableDef { 695impl From<DefId> for TypableDef {
696 fn from(func: DefId) -> TypableDef { 696 fn from(func: DefId) -> TypableDef {
@@ -705,6 +705,7 @@ impl From<ModuleDef> for Option<TypableDef> {
705 ModuleDef::Function(f) => f.into(), 705 ModuleDef::Function(f) => f.into(),
706 ModuleDef::Struct(s) => s.into(), 706 ModuleDef::Struct(s) => s.into(),
707 ModuleDef::Enum(e) => e.into(), 707 ModuleDef::Enum(e) => e.into(),
708 ModuleDef::EnumVariant(v) => v.into(),
708 ModuleDef::Module(_) => return None, 709 ModuleDef::Module(_) => return None,
709 }; 710 };
710 Some(res) 711 Some(res)
@@ -716,48 +717,33 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
716 TypableDef::Function(f) => type_for_fn(db, f), 717 TypableDef::Function(f) => type_for_fn(db, f),
717 TypableDef::Struct(s) => type_for_struct(db, s), 718 TypableDef::Struct(s) => type_for_struct(db, s),
718 TypableDef::Enum(e) => type_for_enum(db, e), 719 TypableDef::Enum(e) => type_for_enum(db, e),
719 TypableDef::Def(def_id) => match def_id.resolve(db) { 720 TypableDef::EnumVariant(v) => type_for_enum_variant(db, v),
720 Def::EnumVariant(ev) => type_for_enum_variant(db, ev), 721 TypableDef::Def(def_id) => {
721 _ => { 722 log::debug!(
722 log::debug!( 723 "trying to get type for item of unknown type {:?} {:?}",
723 "trying to get type for item of unknown type {:?} {:?}", 724 def_id,
724 def_id, 725 def
725 def 726 );
726 ); 727 Ty::Unknown
727 Ty::Unknown 728 }
728 }
729 },
730 } 729 }
731} 730}
732 731
733#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 732#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
734pub enum VariantDef { 733pub enum VariantDef {
735 Struct(Struct), 734 Struct(Struct),
736 Def(DefId), // EnumVariant 735 EnumVariant(EnumVariant),
737}
738impl_froms!(VariantDef: Struct);
739
740impl From<DefId> for VariantDef {
741 fn from(def_id: DefId) -> VariantDef {
742 VariantDef::Def(def_id)
743 }
744} 736}
737impl_froms!(VariantDef: Struct, EnumVariant);
745 738
746pub(super) fn type_for_field(db: &impl HirDatabase, def: VariantDef, field: Name) -> Option<Ty> { 739pub(super) fn type_for_field(db: &impl HirDatabase, def: VariantDef, field: Name) -> Option<Ty> {
747 let (variant_data, generics, module) = match def { 740 let (variant_data, generics, module) = match def {
748 VariantDef::Struct(s) => (s.variant_data(db), s.generic_params(db), s.module(db)), 741 VariantDef::Struct(s) => (s.variant_data(db), s.generic_params(db), s.module(db)),
749 VariantDef::Def(def_id) => match def_id.resolve(db) { 742 VariantDef::EnumVariant(var) => (
750 Def::EnumVariant(ev) => ( 743 var.variant_data(db),
751 ev.variant_data(db), 744 var.parent_enum(db).generic_params(db),
752 ev.parent_enum(db).generic_params(db), 745 var.module(db),
753 def_id.module(db), 746 ),
754 ),
755 // TODO: unions
756 _ => panic!(
757 "trying to get type for field {:?} in non-struct/variant {:?}",
758 field, def_id
759 ),
760 },
761 }; 747 };
762 // We can't have an impl block ere, right? 748 // We can't have an impl block ere, right?
763 // let impl_block = def_id.impl_block(db); 749 // let impl_block = def_id.impl_block(db);
@@ -1156,21 +1142,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1156 def, 1142 def,
1157 ); 1143 );
1158 match def { 1144 match def {
1159 TypableDef::Def(def_id) => match def_id.resolve(self.db) {
1160 Def::EnumVariant(ev) => {
1161 let ty = type_for_enum_variant(self.db, ev);
1162 let ty = self.insert_type_vars(ty.apply_substs(substs));
1163 (ty, Some(def_id.into()))
1164 }
1165 _ => (Ty::Unknown, None),
1166 },
1167 TypableDef::Function(_) => (Ty::Unknown, None),
1168 TypableDef::Struct(s) => { 1145 TypableDef::Struct(s) => {
1169 let ty = type_for_struct(self.db, s); 1146 let ty = type_for_struct(self.db, s);
1170 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1147 let ty = self.insert_type_vars(ty.apply_substs(substs));
1171 (ty, Some(s.into())) 1148 (ty, Some(s.into()))
1172 } 1149 }
1173 TypableDef::Enum(_) => (Ty::Unknown, None), 1150 TypableDef::EnumVariant(var) => {
1151 let ty = type_for_enum_variant(self.db, var);
1152 let ty = self.insert_type_vars(ty.apply_substs(substs));
1153 (ty, Some(var.into()))
1154 }
1155 TypableDef::Def(_) | TypableDef::Enum(_) | TypableDef::Function(_) => {
1156 (Ty::Unknown, None)
1157 }
1174 } 1158 }
1175 } 1159 }
1176 1160
@@ -1181,13 +1165,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1181 let fields = s.fields(self.db); 1165 let fields = s.fields(self.db);
1182 Some((ty, fields)) 1166 Some((ty, fields))
1183 } 1167 }
1184 VariantDef::Def(def_id) => match def_id.resolve(self.db) { 1168 VariantDef::EnumVariant(var) => {
1185 Def::EnumVariant(ev) => { 1169 let fields = var.fields(self.db);
1186 let fields = ev.fields(self.db); 1170 Some((ty, fields))
1187 Some((ty, fields)) 1171 }
1188 }
1189 _ => None,
1190 },
1191 } 1172 }
1192 } 1173 }
1193 1174
@@ -1285,13 +1266,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1285 .module 1266 .module
1286 .resolve_path(self.db, &path) 1267 .resolve_path(self.db, &path)
1287 .take_values() 1268 .take_values()
1288 .and_then(|module_def| match module_def { 1269 .and_then(|module_def| module_def.into())
1289 ModuleDef::Def(it) => Some(it.into()),
1290 ModuleDef::Function(func) => Some(func.into()),
1291 ModuleDef::Struct(s) => Some(s.into()),
1292 ModuleDef::Enum(e) => Some(e.into()),
1293 ModuleDef::Module(_) => None,
1294 })
1295 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), 1270 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)),
1296 Pat::Bind { 1271 Pat::Bind {
1297 mode, 1272 mode,