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.rs23
-rw-r--r--crates/ra_hir/src/ty/lower.rs70
2 files changed, 57 insertions, 36 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 268d2c110..2eb73726e 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -724,11 +724,11 @@ 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, sig, .. } => {
729 let ret_ty = sig.output.clone().subst(&substs); 729 let ret_ty = sig.ret().clone().subst(&substs);
730 let param_tys = 730 let param_tys =
731 sig.input.iter().map(|ty| ty.clone().subst(&substs)).collect(); 731 sig.params().iter().map(|ty| ty.clone().subst(&substs)).collect();
732 (param_tys, ret_ty) 732 (param_tys, ret_ty)
733 } 733 }
734 _ => { 734 _ => {
@@ -762,19 +762,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
762 let method_ty = self.insert_type_vars(method_ty); 762 let method_ty = self.insert_type_vars(method_ty);
763 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { 763 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
764 Ty::FnPtr(sig) => { 764 Ty::FnPtr(sig) => {
765 if !sig.input.is_empty() { 765 if !sig.params().is_empty() {
766 (sig.input[0].clone(), sig.input[1..].to_vec(), sig.output.clone()) 766 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone())
767 } else { 767 } else {
768 (Ty::Unknown, Vec::new(), sig.output.clone()) 768 (Ty::Unknown, Vec::new(), sig.ret().clone())
769 } 769 }
770 } 770 }
771 Ty::FnDef { substs, sig, .. } => { 771 Ty::FnDef { substs, sig, .. } => {
772 let ret_ty = sig.output.clone().subst(&substs); 772 let ret_ty = sig.ret().clone().subst(&substs);
773 773
774 if !sig.input.is_empty() { 774 if !sig.params().is_empty() {
775 let mut arg_iter = sig.input.iter().map(|ty| ty.clone().subst(&substs)); 775 let mut params_iter =
776 let receiver_ty = arg_iter.next().unwrap(); 776 sig.params().iter().map(|ty| ty.clone().subst(&substs));
777 (receiver_ty, arg_iter.collect(), ret_ty) 777 let receiver_ty = params_iter.next().unwrap();
778 (receiver_ty, params_iter.collect(), ret_ty)
778 } else { 779 } else {
779 (Ty::Unknown, Vec::new(), ret_ty) 780 (Ty::Unknown, Vec::new(), ret_ty)
780 } 781 }
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index ee4508bb2..7d065203a 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 }
@@ -226,16 +224,20 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
226 Ty::from_hir(db, &resolver, type_ref) 224 Ty::from_hir(db, &resolver, type_ref)
227} 225}
228 226
227fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
228 let signature = def.signature(db);
229 let resolver = def.resolver(db);
230 let params =
231 signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
232 let ret = Ty::from_hir(db, &resolver, signature.ret_type());
233 FnSig::from_params_and_return(params, ret)
234}
235
229/// Build the declared type of a function. This should not need to look at the 236/// Build the declared type of a function. This should not need to look at the
230/// function body. 237/// function body.
231fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 238fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
232 let signature = def.signature(db); 239 let sig = fn_sig_for_fn(db, def);
233 let resolver = def.resolver(db);
234 let generics = def.generic_params(db); 240 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); 241 let substs = make_substs(&generics);
240 Ty::FnDef { def: def.into(), sig, substs } 242 Ty::FnDef { def: def.into(), sig, substs }
241} 243}
@@ -256,41 +258,59 @@ fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty {
256 Ty::from_hir(db, &resolver, signature.type_ref()) 258 Ty::from_hir(db, &resolver, signature.type_ref())
257} 259}
258 260
259/// Build the type of a tuple struct constructor. 261fn 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); 262 let var_data = def.variant_data(db);
262 let fields = match var_data.fields() { 263 let fields = match var_data.fields() {
263 Some(fields) => fields, 264 Some(fields) => fields,
264 None => return type_for_struct(db, def), // Unit struct 265 None => panic!("fn_sig_for_struct_constructor called on unit struct"),
265 }; 266 };
266 let resolver = def.resolver(db); 267 let resolver = def.resolver(db);
267 let generics = def.generic_params(db); 268 let params = fields
268 let input = fields
269 .iter() 269 .iter()
270 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 270 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
271 .collect::<Vec<_>>(); 271 .collect::<Vec<_>>();
272 let output = type_for_struct(db, def); 272 let ret = type_for_struct(db, def);
273 let sig = Arc::new(FnSig { input, output }); 273 FnSig::from_params_and_return(params, ret)
274}
275
276/// Build the type of a tuple struct constructor.
277fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
278 let var_data = def.variant_data(db);
279 if var_data.fields().is_none() {
280 return type_for_struct(db, def); // Unit struct
281 }
282 let sig = fn_sig_for_struct_constructor(db, def);
283 let generics = def.generic_params(db);
274 let substs = make_substs(&generics); 284 let substs = make_substs(&generics);
275 Ty::FnDef { def: def.into(), sig, substs } 285 Ty::FnDef { def: def.into(), sig, substs }
276} 286}
277 287
278/// Build the type of a tuple enum variant constructor. 288fn 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); 289 let var_data = def.variant_data(db);
281 let fields = match var_data.fields() { 290 let fields = match var_data.fields() {
282 Some(fields) => fields, 291 Some(fields) => fields,
283 None => return type_for_enum(db, def.parent_enum(db)), // Unit variant 292 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"),
284 }; 293 };
285 let resolver = def.parent_enum(db).resolver(db); 294 let resolver = def.parent_enum(db).resolver(db);
286 let generics = def.parent_enum(db).generic_params(db); 295 let params = fields
287 let input = fields
288 .iter() 296 .iter()
289 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 297 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
290 .collect::<Vec<_>>(); 298 .collect::<Vec<_>>();
299 let generics = def.parent_enum(db).generic_params(db);
300 let substs = make_substs(&generics);
301 let ret = type_for_enum(db, def.parent_enum(db)).subst(&substs);
302 FnSig::from_params_and_return(params, ret)
303}
304
305/// Build the type of a tuple enum variant constructor.
306fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
307 let var_data = def.variant_data(db);
308 if var_data.fields().is_none() {
309 return type_for_enum(db, def.parent_enum(db)); // Unit variant
310 }
311 let sig = fn_sig_for_enum_variant_constructor(db, def);
312 let generics = def.parent_enum(db).generic_params(db);
291 let substs = make_substs(&generics); 313 let substs = make_substs(&generics);
292 let output = type_for_enum(db, def.parent_enum(db)).subst(&substs);
293 let sig = Arc::new(FnSig { input, output });
294 Ty::FnDef { def: def.into(), sig, substs } 314 Ty::FnDef { def: def.into(), sig, substs }
295} 315}
296 316