diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 90 |
1 files changed, 59 insertions, 31 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index fc699a2ae..6a5f4fae6 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -166,27 +166,28 @@ impl Substs { | |||
166 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 166 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
167 | pub enum AdtDef { | 167 | pub enum AdtDef { |
168 | Struct(Struct), | 168 | Struct(Struct), |
169 | Def(DefId), // Enum | 169 | Enum(Enum), |
170 | } | 170 | } |
171 | 171 | ||
172 | impl From<Struct> for AdtDef { | 172 | impl From<Struct> for AdtDef { |
173 | fn from(struct_: Struct) -> AdtDef { | 173 | fn from(s: Struct) -> AdtDef { |
174 | AdtDef::Struct(struct_) | 174 | AdtDef::Struct(s) |
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | impl From<DefId> for AdtDef { | 178 | impl From<Enum> for AdtDef { |
179 | fn from(def_id: DefId) -> AdtDef { | 179 | fn from(e: Enum) -> AdtDef { |
180 | AdtDef::Def(def_id) | 180 | AdtDef::Enum(e) |
181 | } | 181 | } |
182 | } | 182 | } |
183 | 183 | ||
184 | impl AdtDef { | 184 | impl AdtDef { |
185 | fn krate(self, db: &impl HirDatabase) -> Option<Crate> { | 185 | fn krate(self, db: &impl HirDatabase) -> Option<Crate> { |
186 | match self { | 186 | match self { |
187 | AdtDef::Struct(s) => s.module(db).krate(db), | 187 | AdtDef::Struct(s) => s.module(db), |
188 | AdtDef::Def(def_id) => def_id.krate(db), | 188 | AdtDef::Enum(e) => e.module(db), |
189 | } | 189 | } |
190 | .krate(db) | ||
190 | } | 191 | } |
191 | } | 192 | } |
192 | 193 | ||
@@ -408,14 +409,16 @@ impl Ty { | |||
408 | } | 409 | } |
409 | 410 | ||
410 | // Resolve in module (in type namespace) | 411 | // Resolve in module (in type namespace) |
411 | let resolved = match module.resolve_path(db, path).take_types() { | 412 | let typable: TypableDef = match module |
412 | Some(ModuleDef::Def(r)) => r.into(), | 413 | .resolve_path(db, path) |
413 | Some(ModuleDef::Function(f)) => f.into(), | 414 | .take_types() |
414 | Some(ModuleDef::Struct(s)) => s.into(), | 415 | .and_then(|it| it.into()) |
415 | None | Some(ModuleDef::Module(_)) => return Ty::Unknown, | 416 | { |
417 | None => return Ty::Unknown, | ||
418 | Some(it) => it, | ||
416 | }; | 419 | }; |
417 | let ty = db.type_for_def(resolved); | 420 | let ty = db.type_for_def(typable); |
418 | let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved); | 421 | let substs = Ty::substs_from_path(db, module, impl_block, generics, path, typable); |
419 | ty.apply_substs(substs) | 422 | ty.apply_substs(substs) |
420 | } | 423 | } |
421 | 424 | ||
@@ -438,9 +441,8 @@ impl Ty { | |||
438 | let (def_generics, segment) = match resolved { | 441 | let (def_generics, segment) = match resolved { |
439 | TypableDef::Function(func) => (func.generic_params(db), last), | 442 | TypableDef::Function(func) => (func.generic_params(db), last), |
440 | TypableDef::Struct(s) => (s.generic_params(db), last), | 443 | TypableDef::Struct(s) => (s.generic_params(db), last), |
444 | TypableDef::Enum(e) => (e.generic_params(db), last), | ||
441 | TypableDef::Def(def_id) => match def_id.resolve(db) { | 445 | TypableDef::Def(def_id) => match def_id.resolve(db) { |
442 | Def::Struct(s) => (s.generic_params(db), last), | ||
443 | Def::Enum(e) => (e.generic_params(db), last), | ||
444 | Def::Trait(t) => (t.generic_params(db), last), | 446 | Def::Trait(t) => (t.generic_params(db), last), |
445 | Def::EnumVariant(ev) => { | 447 | Def::EnumVariant(ev) => { |
446 | // the generic args for an enum variant may be either specified | 448 | // the generic args for an enum variant may be either specified |
@@ -680,7 +682,7 @@ fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { | |||
680 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { | 682 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { |
681 | let generics = s.generic_params(db); | 683 | let generics = s.generic_params(db); |
682 | Ty::Adt { | 684 | Ty::Adt { |
683 | def_id: s.def_id().into(), | 685 | def_id: s.into(), |
684 | name: s.name(db).unwrap_or_else(Name::missing), | 686 | name: s.name(db).unwrap_or_else(Name::missing), |
685 | substs: make_substs(&generics), | 687 | substs: make_substs(&generics), |
686 | } | 688 | } |
@@ -696,6 +698,7 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T | |||
696 | pub enum TypableDef { | 698 | pub enum TypableDef { |
697 | Function(Function), | 699 | Function(Function), |
698 | Struct(Struct), | 700 | Struct(Struct), |
701 | Enum(Enum), | ||
699 | Def(DefId), | 702 | Def(DefId), |
700 | } | 703 | } |
701 | 704 | ||
@@ -706,8 +709,14 @@ impl From<Function> for TypableDef { | |||
706 | } | 709 | } |
707 | 710 | ||
708 | impl From<Struct> for TypableDef { | 711 | impl From<Struct> for TypableDef { |
709 | fn from(struct_: Struct) -> TypableDef { | 712 | fn from(s: Struct) -> TypableDef { |
710 | TypableDef::Struct(struct_) | 713 | TypableDef::Struct(s) |
714 | } | ||
715 | } | ||
716 | |||
717 | impl From<Enum> for TypableDef { | ||
718 | fn from(e: Enum) -> TypableDef { | ||
719 | TypableDef::Enum(e) | ||
711 | } | 720 | } |
712 | } | 721 | } |
713 | 722 | ||
@@ -717,10 +726,24 @@ impl From<DefId> for TypableDef { | |||
717 | } | 726 | } |
718 | } | 727 | } |
719 | 728 | ||
729 | impl From<ModuleDef> for Option<TypableDef> { | ||
730 | fn from(def: ModuleDef) -> Option<TypableDef> { | ||
731 | let res = match def { | ||
732 | ModuleDef::Def(r) => r.into(), | ||
733 | ModuleDef::Function(f) => f.into(), | ||
734 | ModuleDef::Struct(s) => s.into(), | ||
735 | ModuleDef::Enum(e) => e.into(), | ||
736 | ModuleDef::Module(_) => return None, | ||
737 | }; | ||
738 | Some(res) | ||
739 | } | ||
740 | } | ||
741 | |||
720 | pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { | 742 | pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { |
721 | match def { | 743 | match def { |
722 | TypableDef::Function(f) => type_for_fn(db, f), | 744 | TypableDef::Function(f) => type_for_fn(db, f), |
723 | TypableDef::Struct(s) => type_for_struct(db, s), | 745 | TypableDef::Struct(s) => type_for_struct(db, s), |
746 | TypableDef::Enum(e) => type_for_enum(db, e), | ||
724 | TypableDef::Def(def_id) => match def_id.resolve(db) { | 747 | TypableDef::Def(def_id) => match def_id.resolve(db) { |
725 | Def::Enum(e) => type_for_enum(db, e), | 748 | Def::Enum(e) => type_for_enum(db, e), |
726 | Def::EnumVariant(ev) => type_for_enum_variant(db, ev), | 749 | Def::EnumVariant(ev) => type_for_enum_variant(db, ev), |
@@ -1134,12 +1157,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1134 | }; | 1157 | }; |
1135 | 1158 | ||
1136 | // resolve in module | 1159 | // resolve in module |
1137 | let typable = match self.module.resolve_path(self.db, &path).take_values()? { | 1160 | let typable: Option<TypableDef> = self |
1138 | ModuleDef::Def(it) => it.into(), | 1161 | .module |
1139 | ModuleDef::Function(func) => func.into(), | 1162 | .resolve_path(self.db, &path) |
1140 | ModuleDef::Struct(s) => s.into(), | 1163 | .take_values()? |
1141 | ModuleDef::Module(_) => return None, | 1164 | .into(); |
1142 | }; | 1165 | let typable = typable?; |
1143 | let ty = self.db.type_for_def(typable); | 1166 | let ty = self.db.type_for_def(typable); |
1144 | let ty = self.insert_type_vars(ty); | 1167 | let ty = self.insert_type_vars(ty); |
1145 | Some(ty) | 1168 | Some(ty) |
@@ -1150,11 +1173,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1150 | Some(path) => path, | 1173 | Some(path) => path, |
1151 | None => return (Ty::Unknown, None), | 1174 | None => return (Ty::Unknown, None), |
1152 | }; | 1175 | }; |
1153 | let def = match self.module.resolve_path(self.db, &path).take_types() { | 1176 | let typable: Option<TypableDef> = self |
1154 | Some(ModuleDef::Def(def_id)) => def_id.into(), | 1177 | .module |
1155 | Some(ModuleDef::Function(func)) => func.into(), | 1178 | .resolve_path(self.db, &path) |
1156 | Some(ModuleDef::Struct(s)) => s.into(), | 1179 | .take_types() |
1157 | None | Some(ModuleDef::Module(_)) => return (Ty::Unknown, None), | 1180 | .and_then(|it| it.into()); |
1181 | let def = match typable { | ||
1182 | None => return (Ty::Unknown, None), | ||
1183 | Some(it) => it, | ||
1158 | }; | 1184 | }; |
1159 | // TODO remove the duplication between here and `Ty::from_path`? | 1185 | // TODO remove the duplication between here and `Ty::from_path`? |
1160 | // TODO provide generics of function | 1186 | // TODO provide generics of function |
@@ -1182,6 +1208,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1182 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 1208 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
1183 | (ty, Some(s.into())) | 1209 | (ty, Some(s.into())) |
1184 | } | 1210 | } |
1211 | TypableDef::Enum(_) => (Ty::Unknown, None), | ||
1185 | } | 1212 | } |
1186 | } | 1213 | } |
1187 | 1214 | ||
@@ -1300,6 +1327,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1300 | ModuleDef::Def(it) => Some(it.into()), | 1327 | ModuleDef::Def(it) => Some(it.into()), |
1301 | ModuleDef::Function(func) => Some(func.into()), | 1328 | ModuleDef::Function(func) => Some(func.into()), |
1302 | ModuleDef::Struct(s) => Some(s.into()), | 1329 | ModuleDef::Struct(s) => Some(s.into()), |
1330 | ModuleDef::Enum(e) => Some(e.into()), | ||
1303 | ModuleDef::Module(_) => None, | 1331 | ModuleDef::Module(_) => None, |
1304 | }) | 1332 | }) |
1305 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), | 1333 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), |