diff options
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 32 |
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 | ||
11 | use crate::{ | 11 | use 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 | ||
305 | fn 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)] |
302 | pub enum TypableDef { | 315 | pub 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 | } |
308 | impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant); | 322 | impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant, Type); |
309 | 323 | ||
310 | impl From<ModuleDef> for Option<TypableDef> { | 324 | impl 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 | } |