aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r--crates/ra_hir/src/ty/lower.rs70
1 files changed, 45 insertions, 25 deletions
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