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.rs32
1 files changed, 23 insertions, 9 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 63e13a30e..a11d964c8 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -10,7 +10,7 @@ use std::sync::Arc;
10 10
11use crate::{ 11use crate::{
12 Function, Struct, StructField, Enum, EnumVariant, Path, Name, 12 Function, Struct, StructField, Enum, EnumVariant, Path, Name,
13 ModuleDef, 13 ModuleDef, Type,
14 HirDatabase, 14 HirDatabase,
15 type_ref::TypeRef, 15 type_ref::TypeRef,
16 name::KnownName, 16 name::KnownName,
@@ -109,7 +109,7 @@ impl Ty {
109 }; 109 };
110 let ty = db.type_for_def(typable, Namespace::Types); 110 let ty = db.type_for_def(typable, Namespace::Types);
111 let substs = Ty::substs_from_path(db, resolver, path, typable); 111 let substs = Ty::substs_from_path(db, resolver, path, typable);
112 ty.apply_substs(substs) 112 ty.subst(&substs)
113 } 113 }
114 114
115 pub(super) fn substs_from_path_segment( 115 pub(super) fn substs_from_path_segment(
@@ -124,6 +124,7 @@ impl Ty {
124 TypableDef::Struct(s) => s.generic_params(db), 124 TypableDef::Struct(s) => s.generic_params(db),
125 TypableDef::Enum(e) => e.generic_params(db), 125 TypableDef::Enum(e) => e.generic_params(db),
126 TypableDef::EnumVariant(var) => var.parent_enum(db).generic_params(db), 126 TypableDef::EnumVariant(var) => var.parent_enum(db).generic_params(db),
127 TypableDef::Type(t) => t.generic_params(db),
127 }; 128 };
128 let parent_param_count = def_generics.count_parent_params(); 129 let parent_param_count = def_generics.count_parent_params();
129 substs.extend((0..parent_param_count).map(|_| Ty::Unknown)); 130 substs.extend((0..parent_param_count).map(|_| Ty::Unknown));
@@ -159,9 +160,10 @@ impl Ty {
159 ) -> Substs { 160 ) -> Substs {
160 let last = path.segments.last().expect("path should have at least one segment"); 161 let last = path.segments.last().expect("path should have at least one segment");
161 let segment = match resolved { 162 let segment = match resolved {
162 TypableDef::Function(_) => last, 163 TypableDef::Function(_)
163 TypableDef::Struct(_) => last, 164 | TypableDef::Struct(_)
164 TypableDef::Enum(_) => last, 165 | TypableDef::Enum(_)
166 | TypableDef::Type(_) => last,
165 TypableDef::EnumVariant(_) => { 167 TypableDef::EnumVariant(_) => {
166 // the generic args for an enum variant may be either specified 168 // the generic args for an enum variant may be either specified
167 // on the segment referring to the enum, or on the segment 169 // on the segment referring to the enum, or on the segment
@@ -194,11 +196,13 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace
194 (TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s), 196 (TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s),
195 (TypableDef::Enum(e), Namespace::Types) => type_for_enum(db, e), 197 (TypableDef::Enum(e), Namespace::Types) => type_for_enum(db, e),
196 (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v), 198 (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v),
199 (TypableDef::Type(t), Namespace::Types) => type_for_type_alias(db, t),
197 200
198 // 'error' cases: 201 // 'error' cases:
199 (TypableDef::Function(_), Namespace::Types) => Ty::Unknown, 202 (TypableDef::Function(_), Namespace::Types) => Ty::Unknown,
200 (TypableDef::Enum(_), Namespace::Values) => Ty::Unknown, 203 (TypableDef::Enum(_), Namespace::Values) => Ty::Unknown,
201 (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown, 204 (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown,
205 (TypableDef::Type(_), Namespace::Values) => Ty::Unknown,
202 } 206 }
203} 207}
204 208
@@ -264,7 +268,7 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) ->
264 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 268 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
265 .collect::<Vec<_>>(); 269 .collect::<Vec<_>>();
266 let substs = make_substs(&generics); 270 let substs = make_substs(&generics);
267 let output = type_for_enum(db, def.parent_enum(db)).apply_substs(substs.clone()); 271 let output = type_for_enum(db, def.parent_enum(db)).subst(&substs);
268 let sig = Arc::new(FnSig { input, output }); 272 let sig = Arc::new(FnSig { input, output });
269 Ty::FnDef { def: def.into(), sig, name, substs } 273 Ty::FnDef { def: def.into(), sig, name, substs }
270} 274}
@@ -298,14 +302,24 @@ fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
298 } 302 }
299} 303}
300 304
305fn type_for_type_alias(db: &impl HirDatabase, t: Type) -> Ty {
306 let generics = t.generic_params(db);
307 let resolver = t.resolver(db);
308 let type_ref = t.type_ref(db);
309 let substs = make_substs(&generics);
310 let inner = Ty::from_hir(db, &resolver, &type_ref);
311 inner.subst(&substs)
312}
313
301#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 314#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
302pub enum TypableDef { 315pub enum TypableDef {
303 Function(Function), 316 Function(Function),
304 Struct(Struct), 317 Struct(Struct),
305 Enum(Enum), 318 Enum(Enum),
306 EnumVariant(EnumVariant), 319 EnumVariant(EnumVariant),
320 Type(Type),
307} 321}
308impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant); 322impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant, Type);
309 323
310impl From<ModuleDef> for Option<TypableDef> { 324impl From<ModuleDef> for Option<TypableDef> {
311 fn from(def: ModuleDef) -> Option<TypableDef> { 325 fn from(def: ModuleDef) -> Option<TypableDef> {
@@ -314,11 +328,11 @@ impl From<ModuleDef> for Option<TypableDef> {
314 ModuleDef::Struct(s) => s.into(), 328 ModuleDef::Struct(s) => s.into(),
315 ModuleDef::Enum(e) => e.into(), 329 ModuleDef::Enum(e) => e.into(),
316 ModuleDef::EnumVariant(v) => v.into(), 330 ModuleDef::EnumVariant(v) => v.into(),
331 ModuleDef::Type(t) => t.into(),
317 ModuleDef::Const(_) 332 ModuleDef::Const(_)
318 | ModuleDef::Static(_) 333 | ModuleDef::Static(_)
319 | ModuleDef::Module(_) 334 | ModuleDef::Module(_)
320 | ModuleDef::Trait(_) 335 | ModuleDef::Trait(_) => return None,
321 | ModuleDef::Type(_) => return None,
322 }; 336 };
323 Some(res) 337 Some(res)
324 } 338 }