aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/infer.rs31
-rw-r--r--crates/ra_hir/src/ty/lower.rs82
-rw-r--r--crates/ra_hir/src/ty/primitive.rs64
3 files changed, 102 insertions, 75 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 268d2c110..c9a5bc7a1 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -724,11 +724,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
724 Expr::Call { callee, args } => { 724 Expr::Call { callee, args } => {
725 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 725 let callee_ty = self.infer_expr(*callee, &Expectation::none());
726 let (param_tys, ret_ty) = match &callee_ty { 726 let (param_tys, ret_ty) = match &callee_ty {
727 Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), 727 Ty::FnPtr(sig) => (sig.params().to_vec(), sig.ret().clone()),
728 Ty::FnDef { substs, sig, .. } => { 728 Ty::FnDef { substs, def, .. } => {
729 let ret_ty = sig.output.clone().subst(&substs); 729 let sig = self.db.callable_item_signature(*def);
730 let ret_ty = sig.ret().clone().subst(&substs);
730 let param_tys = 731 let param_tys =
731 sig.input.iter().map(|ty| ty.clone().subst(&substs)).collect(); 732 sig.params().iter().map(|ty| ty.clone().subst(&substs)).collect();
732 (param_tys, ret_ty) 733 (param_tys, ret_ty)
733 } 734 }
734 _ => { 735 _ => {
@@ -762,19 +763,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
762 let method_ty = self.insert_type_vars(method_ty); 763 let method_ty = self.insert_type_vars(method_ty);
763 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { 764 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
764 Ty::FnPtr(sig) => { 765 Ty::FnPtr(sig) => {
765 if !sig.input.is_empty() { 766 if !sig.params().is_empty() {
766 (sig.input[0].clone(), sig.input[1..].to_vec(), sig.output.clone()) 767 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone())
767 } else { 768 } else {
768 (Ty::Unknown, Vec::new(), sig.output.clone()) 769 (Ty::Unknown, Vec::new(), sig.ret().clone())
769 } 770 }
770 } 771 }
771 Ty::FnDef { substs, sig, .. } => { 772 Ty::FnDef { substs, def, .. } => {
772 let ret_ty = sig.output.clone().subst(&substs); 773 let sig = self.db.callable_item_signature(*def);
773 774 let ret_ty = sig.ret().clone().subst(&substs);
774 if !sig.input.is_empty() { 775
775 let mut arg_iter = sig.input.iter().map(|ty| ty.clone().subst(&substs)); 776 if !sig.params().is_empty() {
776 let receiver_ty = arg_iter.next().unwrap(); 777 let mut params_iter =
777 (receiver_ty, arg_iter.collect(), ret_ty) 778 sig.params().iter().map(|ty| ty.clone().subst(&substs));
779 let receiver_ty = params_iter.next().unwrap();
780 (receiver_ty, params_iter.collect(), ret_ty)
778 } else { 781 } else {
779 (Ty::Unknown, Vec::new(), ret_ty) 782 (Ty::Unknown, Vec::new(), ret_ty)
780 } 783 }
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index ee4508bb2..278f592d3 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -51,12 +51,10 @@ impl Ty {
51 } 51 }
52 TypeRef::Placeholder => Ty::Unknown, 52 TypeRef::Placeholder => Ty::Unknown,
53 TypeRef::Fn(params) => { 53 TypeRef::Fn(params) => {
54 let mut inner_tys = 54 let inner_tys =
55 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); 55 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
56 let return_ty = 56 let sig = FnSig { params_and_return: inner_tys.into() };
57 inner_tys.pop().expect("TypeRef::Fn should always have at least return type"); 57 Ty::FnPtr(sig)
58 let sig = FnSig { input: inner_tys, output: return_ty };
59 Ty::FnPtr(Arc::new(sig))
60 } 58 }
61 TypeRef::Error => Ty::Unknown, 59 TypeRef::Error => Ty::Unknown,
62 } 60 }
@@ -214,6 +212,15 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace
214 } 212 }
215} 213}
216 214
215/// Build the signature of a callable item (function, struct or enum variant).
216pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig {
217 match def {
218 CallableDef::Function(f) => fn_sig_for_fn(db, f),
219 CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s),
220 CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e),
221 }
222}
223
217/// Build the type of a specific field of a struct or enum variant. 224/// Build the type of a specific field of a struct or enum variant.
218pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 225pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
219 let parent_def = field.parent_def(db); 226 let parent_def = field.parent_def(db);
@@ -226,18 +233,21 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
226 Ty::from_hir(db, &resolver, type_ref) 233 Ty::from_hir(db, &resolver, type_ref)
227} 234}
228 235
236fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
237 let signature = def.signature(db);
238 let resolver = def.resolver(db);
239 let params =
240 signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
241 let ret = Ty::from_hir(db, &resolver, signature.ret_type());
242 FnSig::from_params_and_return(params, ret)
243}
244
229/// Build the declared type of a function. This should not need to look at the 245/// Build the declared type of a function. This should not need to look at the
230/// function body. 246/// function body.
231fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 247fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
232 let signature = def.signature(db);
233 let resolver = def.resolver(db);
234 let generics = def.generic_params(db); 248 let generics = def.generic_params(db);
235 let input =
236 signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
237 let output = Ty::from_hir(db, &resolver, signature.ret_type());
238 let sig = Arc::new(FnSig { input, output });
239 let substs = make_substs(&generics); 249 let substs = make_substs(&generics);
240 Ty::FnDef { def: def.into(), sig, substs } 250 Ty::FnDef { def: def.into(), substs }
241} 251}
242 252
243/// Build the declared type of a const. 253/// Build the declared type of a const.
@@ -256,42 +266,58 @@ fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty {
256 Ty::from_hir(db, &resolver, signature.type_ref()) 266 Ty::from_hir(db, &resolver, signature.type_ref())
257} 267}
258 268
259/// Build the type of a tuple struct constructor. 269fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
260fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
261 let var_data = def.variant_data(db); 270 let var_data = def.variant_data(db);
262 let fields = match var_data.fields() { 271 let fields = match var_data.fields() {
263 Some(fields) => fields, 272 Some(fields) => fields,
264 None => return type_for_struct(db, def), // Unit struct 273 None => panic!("fn_sig_for_struct_constructor called on unit struct"),
265 }; 274 };
266 let resolver = def.resolver(db); 275 let resolver = def.resolver(db);
267 let generics = def.generic_params(db); 276 let params = fields
268 let input = fields
269 .iter() 277 .iter()
270 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 278 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
271 .collect::<Vec<_>>(); 279 .collect::<Vec<_>>();
272 let output = type_for_struct(db, def); 280 let ret = type_for_struct(db, def);
273 let sig = Arc::new(FnSig { input, output }); 281 FnSig::from_params_and_return(params, ret)
282}
283
284/// Build the type of a tuple struct constructor.
285fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
286 let var_data = def.variant_data(db);
287 if var_data.fields().is_none() {
288 return type_for_struct(db, def); // Unit struct
289 }
290 let generics = def.generic_params(db);
274 let substs = make_substs(&generics); 291 let substs = make_substs(&generics);
275 Ty::FnDef { def: def.into(), sig, substs } 292 Ty::FnDef { def: def.into(), substs }
276} 293}
277 294
278/// Build the type of a tuple enum variant constructor. 295fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig {
279fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
280 let var_data = def.variant_data(db); 296 let var_data = def.variant_data(db);
281 let fields = match var_data.fields() { 297 let fields = match var_data.fields() {
282 Some(fields) => fields, 298 Some(fields) => fields,
283 None => return type_for_enum(db, def.parent_enum(db)), // Unit variant 299 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"),
284 }; 300 };
285 let resolver = def.parent_enum(db).resolver(db); 301 let resolver = def.parent_enum(db).resolver(db);
286 let generics = def.parent_enum(db).generic_params(db); 302 let params = fields
287 let input = fields
288 .iter() 303 .iter()
289 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 304 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
290 .collect::<Vec<_>>(); 305 .collect::<Vec<_>>();
306 let generics = def.parent_enum(db).generic_params(db);
307 let substs = make_substs(&generics);
308 let ret = type_for_enum(db, def.parent_enum(db)).subst(&substs);
309 FnSig::from_params_and_return(params, ret)
310}
311
312/// Build the type of a tuple enum variant constructor.
313fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
314 let var_data = def.variant_data(db);
315 if var_data.fields().is_none() {
316 return type_for_enum(db, def.parent_enum(db)); // Unit variant
317 }
318 let generics = def.parent_enum(db).generic_params(db);
291 let substs = make_substs(&generics); 319 let substs = make_substs(&generics);
292 let output = type_for_enum(db, def.parent_enum(db)).subst(&substs); 320 Ty::FnDef { def: def.into(), substs }
293 let sig = Arc::new(FnSig { input, output });
294 Ty::FnDef { def: def.into(), sig, substs }
295} 321}
296 322
297fn make_substs(generics: &GenericParams) -> Substs { 323fn make_substs(generics: &GenericParams) -> Substs {
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs
index 5741ca90d..30aeac48e 100644
--- a/crates/ra_hir/src/ty/primitive.rs
+++ b/crates/ra_hir/src/ty/primitive.rs
@@ -10,14 +10,6 @@ pub enum UncertainIntTy {
10} 10}
11 11
12impl UncertainIntTy { 12impl UncertainIntTy {
13 pub fn ty_to_string(&self) -> &'static str {
14 match *self {
15 UncertainIntTy::Unknown => "{integer}",
16 UncertainIntTy::Signed(ty) => ty.ty_to_string(),
17 UncertainIntTy::Unsigned(ty) => ty.ty_to_string(),
18 }
19 }
20
21 pub fn from_name(name: &Name) -> Option<UncertainIntTy> { 13 pub fn from_name(name: &Name) -> Option<UncertainIntTy> {
22 if let Some(ty) = IntTy::from_name(name) { 14 if let Some(ty) = IntTy::from_name(name) {
23 Some(UncertainIntTy::Signed(ty)) 15 Some(UncertainIntTy::Signed(ty))
@@ -29,6 +21,16 @@ impl UncertainIntTy {
29 } 21 }
30} 22}
31 23
24impl fmt::Display for UncertainIntTy {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 match *self {
27 UncertainIntTy::Unknown => write!(f, "{{integer}}"),
28 UncertainIntTy::Signed(ty) => write!(f, "{}", ty),
29 UncertainIntTy::Unsigned(ty) => write!(f, "{}", ty),
30 }
31 }
32}
33
32#[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] 34#[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)]
33pub enum UncertainFloatTy { 35pub enum UncertainFloatTy {
34 Unknown, 36 Unknown,
@@ -36,13 +38,6 @@ pub enum UncertainFloatTy {
36} 38}
37 39
38impl UncertainFloatTy { 40impl UncertainFloatTy {
39 pub fn ty_to_string(&self) -> &'static str {
40 match *self {
41 UncertainFloatTy::Unknown => "{float}",
42 UncertainFloatTy::Known(ty) => ty.ty_to_string(),
43 }
44 }
45
46 pub fn from_name(name: &Name) -> Option<UncertainFloatTy> { 41 pub fn from_name(name: &Name) -> Option<UncertainFloatTy> {
47 if let Some(ty) = FloatTy::from_name(name) { 42 if let Some(ty) = FloatTy::from_name(name) {
48 Some(UncertainFloatTy::Known(ty)) 43 Some(UncertainFloatTy::Known(ty))
@@ -52,6 +47,15 @@ impl UncertainFloatTy {
52 } 47 }
53} 48}
54 49
50impl fmt::Display for UncertainFloatTy {
51 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52 match *self {
53 UncertainFloatTy::Unknown => write!(f, "{{float}}"),
54 UncertainFloatTy::Known(ty) => write!(f, "{}", ty),
55 }
56 }
57}
58
55#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] 59#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
56pub enum IntTy { 60pub enum IntTy {
57 Isize, 61 Isize,
@@ -70,22 +74,19 @@ impl fmt::Debug for IntTy {
70 74
71impl fmt::Display for IntTy { 75impl fmt::Display for IntTy {
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 76 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73 write!(f, "{}", self.ty_to_string()) 77 let s = match *self {
74 }
75}
76
77impl IntTy {
78 pub fn ty_to_string(&self) -> &'static str {
79 match *self {
80 IntTy::Isize => "isize", 78 IntTy::Isize => "isize",
81 IntTy::I8 => "i8", 79 IntTy::I8 => "i8",
82 IntTy::I16 => "i16", 80 IntTy::I16 => "i16",
83 IntTy::I32 => "i32", 81 IntTy::I32 => "i32",
84 IntTy::I64 => "i64", 82 IntTy::I64 => "i64",
85 IntTy::I128 => "i128", 83 IntTy::I128 => "i128",
86 } 84 };
85 write!(f, "{}", s)
87 } 86 }
87}
88 88
89impl IntTy {
89 pub fn from_name(name: &Name) -> Option<IntTy> { 90 pub fn from_name(name: &Name) -> Option<IntTy> {
90 match name.as_known_name()? { 91 match name.as_known_name()? {
91 KnownName::Isize => Some(IntTy::Isize), 92 KnownName::Isize => Some(IntTy::Isize),
@@ -109,18 +110,21 @@ pub enum UintTy {
109 U128, 110 U128,
110} 111}
111 112
112impl UintTy { 113impl fmt::Display for UintTy {
113 pub fn ty_to_string(&self) -> &'static str { 114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114 match *self { 115 let s = match *self {
115 UintTy::Usize => "usize", 116 UintTy::Usize => "usize",
116 UintTy::U8 => "u8", 117 UintTy::U8 => "u8",
117 UintTy::U16 => "u16", 118 UintTy::U16 => "u16",
118 UintTy::U32 => "u32", 119 UintTy::U32 => "u32",
119 UintTy::U64 => "u64", 120 UintTy::U64 => "u64",
120 UintTy::U128 => "u128", 121 UintTy::U128 => "u128",
121 } 122 };
123 write!(f, "{}", s)
122 } 124 }
125}
123 126
127impl UintTy {
124 pub fn from_name(name: &Name) -> Option<UintTy> { 128 pub fn from_name(name: &Name) -> Option<UintTy> {
125 match name.as_known_name()? { 129 match name.as_known_name()? {
126 KnownName::Usize => Some(UintTy::Usize), 130 KnownName::Usize => Some(UintTy::Usize),
@@ -140,12 +144,6 @@ impl fmt::Debug for UintTy {
140 } 144 }
141} 145}
142 146
143impl fmt::Display for UintTy {
144 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
145 write!(f, "{}", self.ty_to_string())
146 }
147}
148
149#[derive(Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)] 147#[derive(Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)]
150pub enum FloatTy { 148pub enum FloatTy {
151 F32, 149 F32,