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.rs96
1 files changed, 75 insertions, 21 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 562ad1f49..fb98ac907 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -42,7 +42,7 @@ use crate::{
42 generics::GenericParams, 42 generics::GenericParams,
43 path::GenericArg, 43 path::GenericArg,
44 adt::VariantDef, 44 adt::VariantDef,
45 resolve::{Resolver, Resolution}, 45 resolve::{Resolver, Resolution}, nameres::Namespace
46}; 46};
47 47
48/// The ID of a type variable. 48/// The ID of a type variable.
@@ -226,6 +226,8 @@ pub enum Ty {
226 /// function has a unique type, which is output (for a function 226 /// function has a unique type, which is output (for a function
227 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. 227 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
228 /// 228 ///
229 /// This includes tuple struct / enum variant constructors as well.
230 ///
229 /// For example the type of `bar` here: 231 /// For example the type of `bar` here:
230 /// 232 ///
231 /// ```rust 233 /// ```rust
@@ -233,8 +235,8 @@ pub enum Ty {
233 /// let bar = foo; // bar: fn() -> i32 {foo} 235 /// let bar = foo; // bar: fn() -> i32 {foo}
234 /// ``` 236 /// ```
235 FnDef { 237 FnDef {
236 // Function definition 238 /// The definition of the function / constructor.
237 def: Function, 239 def: CallableDef,
238 /// For display 240 /// For display
239 name: Name, 241 name: Name,
240 /// Parameters and return type 242 /// Parameters and return type
@@ -396,7 +398,7 @@ impl Ty {
396 None => return Ty::Unknown, 398 None => return Ty::Unknown,
397 Some(it) => it, 399 Some(it) => it,
398 }; 400 };
399 let ty = db.type_for_def(typable); 401 let ty = db.type_for_def(typable, Namespace::Types);
400 let substs = Ty::substs_from_path(db, resolver, path, typable); 402 let substs = Ty::substs_from_path(db, resolver, path, typable);
401 ty.apply_substs(substs) 403 ty.apply_substs(substs)
402 } 404 }
@@ -673,7 +675,47 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
673 let output = Ty::from_hir(db, &resolver, signature.ret_type()); 675 let output = Ty::from_hir(db, &resolver, signature.ret_type());
674 let sig = Arc::new(FnSig { input, output }); 676 let sig = Arc::new(FnSig { input, output });
675 let substs = make_substs(&generics); 677 let substs = make_substs(&generics);
676 Ty::FnDef { def, sig, name, substs } 678 Ty::FnDef { def: def.into(), sig, name, substs }
679}
680
681/// Compute the type of a tuple struct constructor.
682fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
683 let var_data = def.variant_data(db);
684 let fields = match var_data.fields() {
685 Some(fields) => fields,
686 None => return type_for_struct(db, def), // Unit struct
687 };
688 let resolver = def.resolver(db);
689 let generics = def.generic_params(db);
690 let name = def.name(db).unwrap_or_else(Name::missing);
691 let input = fields
692 .iter()
693 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
694 .collect::<Vec<_>>();
695 let output = type_for_struct(db, def);
696 let sig = Arc::new(FnSig { input, output });
697 let substs = make_substs(&generics);
698 Ty::FnDef { def: def.into(), sig, name, substs }
699}
700
701/// Compute the type of a tuple enum variant constructor.
702fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
703 let var_data = def.variant_data(db);
704 let fields = match var_data.fields() {
705 Some(fields) => fields,
706 None => return type_for_enum(db, def.parent_enum(db)), // Unit variant
707 };
708 let resolver = def.parent_enum(db).resolver(db);
709 let generics = def.parent_enum(db).generic_params(db);
710 let name = def.name(db).unwrap_or_else(Name::missing);
711 let input = fields
712 .iter()
713 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
714 .collect::<Vec<_>>();
715 let output = type_for_enum(db, def.parent_enum(db));
716 let sig = Arc::new(FnSig { input, output });
717 let substs = make_substs(&generics);
718 Ty::FnDef { def: def.into(), sig, name, substs }
677} 719}
678 720
679fn make_substs(generics: &GenericParams) -> Substs { 721fn make_substs(generics: &GenericParams) -> Substs {
@@ -703,12 +745,6 @@ pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
703 } 745 }
704} 746}
705 747
706pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> Ty {
707 let enum_parent = ev.parent_enum(db);
708
709 type_for_enum(db, enum_parent)
710}
711
712#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 748#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
713pub enum TypableDef { 749pub enum TypableDef {
714 Function(Function), 750 Function(Function),
@@ -735,12 +771,26 @@ impl From<ModuleDef> for Option<TypableDef> {
735 } 771 }
736} 772}
737 773
738pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { 774#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
739 match def { 775pub enum CallableDef {
740 TypableDef::Function(f) => type_for_fn(db, f), 776 Function(Function),
741 TypableDef::Struct(s) => type_for_struct(db, s), 777 Struct(Struct),
742 TypableDef::Enum(e) => type_for_enum(db, e), 778 EnumVariant(EnumVariant),
743 TypableDef::EnumVariant(v) => type_for_enum_variant(db, v), 779}
780impl_froms!(CallableDef: Function, Struct, EnumVariant);
781
782pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty {
783 match (def, ns) {
784 (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f),
785 (TypableDef::Struct(s), Namespace::Types) => type_for_struct(db, s),
786 (TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s),
787 (TypableDef::Enum(e), Namespace::Types) => type_for_enum(db, e),
788 (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v),
789
790 // 'error' cases:
791 (TypableDef::Function(_), Namespace::Types) => Ty::Unknown,
792 (TypableDef::Enum(_), Namespace::Values) => Ty::Unknown,
793 (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown,
744 } 794 }
745} 795}
746 796
@@ -1127,7 +1177,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1127 let typable: Option<TypableDef> = def.into(); 1177 let typable: Option<TypableDef> = def.into();
1128 let typable = typable?; 1178 let typable = typable?;
1129 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 1179 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
1130 let ty = self.db.type_for_def(typable).apply_substs(substs); 1180 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
1131 let ty = self.insert_type_vars(ty); 1181 let ty = self.insert_type_vars(ty);
1132 Some(ty) 1182 Some(ty)
1133 } 1183 }
@@ -1178,12 +1228,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1178 let substs = Ty::substs_from_path(self.db, resolver, path, def); 1228 let substs = Ty::substs_from_path(self.db, resolver, path, def);
1179 match def { 1229 match def {
1180 TypableDef::Struct(s) => { 1230 TypableDef::Struct(s) => {
1181 let ty = type_for_struct(self.db, s); 1231 let ty = s.ty(self.db);
1182 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1232 let ty = self.insert_type_vars(ty.apply_substs(substs));
1183 (ty, Some(s.into())) 1233 (ty, Some(s.into()))
1184 } 1234 }
1185 TypableDef::EnumVariant(var) => { 1235 TypableDef::EnumVariant(var) => {
1186 let ty = type_for_enum_variant(self.db, var); 1236 let ty = var.parent_enum(self.db).ty(self.db);
1187 let ty = self.insert_type_vars(ty.apply_substs(substs)); 1237 let ty = self.insert_type_vars(ty.apply_substs(substs));
1188 (ty, Some(var.into())) 1238 (ty, Some(var.into()))
1189 } 1239 }
@@ -1384,7 +1434,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1384 let (derefed_receiver_ty, method_ty, def_generics) = match resolved { 1434 let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
1385 Some((ty, func)) => { 1435 Some((ty, func)) => {
1386 self.write_method_resolution(tgt_expr, func); 1436 self.write_method_resolution(tgt_expr, func);
1387 (ty, self.db.type_for_def(func.into()), Some(func.generic_params(self.db))) 1437 (
1438 ty,
1439 self.db.type_for_def(func.into(), Namespace::Values),
1440 Some(func.generic_params(self.db)),
1441 )
1388 } 1442 }
1389 None => (Ty::Unknown, receiver_ty, None), 1443 None => (Ty::Unknown, receiver_ty, None),
1390 }; 1444 };