diff options
-rw-r--r-- | crates/ra_assists/src/assists/add_new.rs | 45 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_def/src/generics.rs | 97 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/autoderef.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 34 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 44 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 46 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/utils.rs | 83 |
12 files changed, 234 insertions, 204 deletions
diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs index f977547fb..d340cac8f 100644 --- a/crates/ra_assists/src/assists/add_new.rs +++ b/crates/ra_assists/src/assists/add_new.rs | |||
@@ -56,42 +56,39 @@ pub(crate) fn add_new(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
56 | let vis = vis.as_ref().map(String::as_str).unwrap_or(""); | 56 | let vis = vis.as_ref().map(String::as_str).unwrap_or(""); |
57 | write!(&mut buf, " {}fn new(", vis).unwrap(); | 57 | write!(&mut buf, " {}fn new(", vis).unwrap(); |
58 | 58 | ||
59 | join(field_list.fields().map(|f| { | 59 | join(field_list.fields().filter_map(|f| { |
60 | format!( | 60 | Some(format!("{}: {}", f.name()?.syntax().text(), f.ascribed_type()?.syntax().text())) |
61 | "{}: {}", | ||
62 | f.name().unwrap().syntax().text(), | ||
63 | f.ascribed_type().unwrap().syntax().text() | ||
64 | ) | ||
65 | })) | 61 | })) |
66 | .separator(", ") | 62 | .separator(", ") |
67 | .to_buf(&mut buf); | 63 | .to_buf(&mut buf); |
68 | 64 | ||
69 | buf.push_str(") -> Self { Self {"); | 65 | buf.push_str(") -> Self { Self {"); |
70 | 66 | ||
71 | join(field_list.fields().map(|f| f.name().unwrap().syntax().text())) | 67 | join(field_list.fields().filter_map(|f| Some(f.name()?.syntax().text()))) |
72 | .separator(", ") | 68 | .separator(", ") |
73 | .surround_with(" ", " ") | 69 | .surround_with(" ", " ") |
74 | .to_buf(&mut buf); | 70 | .to_buf(&mut buf); |
75 | 71 | ||
76 | buf.push_str("} }"); | 72 | buf.push_str("} }"); |
77 | 73 | ||
78 | let (start_offset, end_offset) = if let Some(impl_block) = impl_block { | 74 | let (start_offset, end_offset) = impl_block |
79 | buf.push('\n'); | 75 | .and_then(|impl_block| { |
80 | let start = impl_block | 76 | buf.push('\n'); |
81 | .syntax() | 77 | let start = impl_block |
82 | .descendants_with_tokens() | 78 | .syntax() |
83 | .find(|t| t.kind() == T!['{']) | 79 | .descendants_with_tokens() |
84 | .unwrap() | 80 | .find(|t| t.kind() == T!['{'])? |
85 | .text_range() | 81 | .text_range() |
86 | .end(); | 82 | .end(); |
87 | 83 | ||
88 | (start, TextUnit::from_usize(1)) | 84 | Some((start, TextUnit::from_usize(1))) |
89 | } else { | 85 | }) |
90 | buf = generate_impl_text(&strukt, &buf); | 86 | .unwrap_or_else(|| { |
91 | let start = strukt.syntax().text_range().end(); | 87 | buf = generate_impl_text(&strukt, &buf); |
92 | 88 | let start = strukt.syntax().text_range().end(); | |
93 | (start, TextUnit::from_usize(3)) | 89 | |
94 | }; | 90 | (start, TextUnit::from_usize(3)) |
91 | }); | ||
95 | 92 | ||
96 | edit.set_cursor(start_offset + TextUnit::of_str(&buf) - end_offset); | 93 | edit.set_cursor(start_offset + TextUnit::of_str(&buf) - end_offset); |
97 | edit.insert(start_offset, buf); | 94 | edit.insert(start_offset, buf); |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 7706399ae..29ace8479 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -15,7 +15,7 @@ use hir_def::{ | |||
15 | per_ns::PerNs, | 15 | per_ns::PerNs, |
16 | resolver::HasResolver, | 16 | resolver::HasResolver, |
17 | type_ref::{Mutability, TypeRef}, | 17 | type_ref::{Mutability, TypeRef}, |
18 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, | 18 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericParamId, |
19 | HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, | 19 | HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, |
20 | Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, | 20 | Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, |
21 | }; | 21 | }; |
@@ -857,8 +857,7 @@ impl Local { | |||
857 | 857 | ||
858 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 858 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
859 | pub struct GenericParam { | 859 | pub struct GenericParam { |
860 | pub(crate) parent: GenericDefId, | 860 | pub(crate) id: GenericParamId, |
861 | pub(crate) idx: u32, | ||
862 | } | 861 | } |
863 | 862 | ||
864 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 863 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 0e136b904..8c4b635d2 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -262,10 +262,7 @@ impl SourceAnalyzer { | |||
262 | ) -> Option<PathResolution> { | 262 | ) -> Option<PathResolution> { |
263 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { | 263 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { |
264 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 264 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
265 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { | 265 | TypeNs::GenericParam(id) => PathResolution::GenericParam(GenericParam { id }), |
266 | parent: self.resolver.generic_def().unwrap(), | ||
267 | idx, | ||
268 | }), | ||
269 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | 266 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
270 | PathResolution::Def(Adt::from(it).into()) | 267 | PathResolution::Def(Adt::from(it).into()) |
271 | } | 268 | } |
@@ -337,10 +334,7 @@ impl SourceAnalyzer { | |||
337 | resolver::ScopeDef::PerNs(it) => it.into(), | 334 | resolver::ScopeDef::PerNs(it) => it.into(), |
338 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), | 335 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), |
339 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), | 336 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), |
340 | resolver::ScopeDef::GenericParam(idx) => { | 337 | resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(GenericParam { id }), |
341 | let parent = self.resolver.generic_def().unwrap(); | ||
342 | ScopeDef::GenericParam(GenericParam { parent, idx }) | ||
343 | } | ||
344 | resolver::ScopeDef::Local(pat_id) => { | 338 | resolver::ScopeDef::Local(pat_id) => { |
345 | let parent = self.resolver.body_owner().unwrap().into(); | 339 | let parent = self.resolver.body_owner().unwrap().into(); |
346 | ScopeDef::Local(Local { parent, pat_id }) | 340 | ScopeDef::Local(Local { parent, pat_id }) |
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 5f648ffc3..94ce83564 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs | |||
@@ -5,20 +5,19 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use hir_expand::name::{self, AsName, Name}; | 7 | use hir_expand::name::{self, AsName, Name}; |
8 | use ra_arena::Arena; | ||
8 | use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; | 9 | use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; |
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
11 | db::DefDatabase, | 12 | db::DefDatabase, |
12 | src::HasSource, | 13 | src::HasSource, |
13 | type_ref::{TypeBound, TypeRef}, | 14 | type_ref::{TypeBound, TypeRef}, |
14 | AdtId, AstItemDef, ContainerId, GenericDefId, Lookup, | 15 | AdtId, AstItemDef, GenericDefId, LocalGenericParamId, Lookup, |
15 | }; | 16 | }; |
16 | 17 | ||
17 | /// Data about a generic parameter (to a function, struct, impl, ...). | 18 | /// Data about a generic parameter (to a function, struct, impl, ...). |
18 | #[derive(Clone, PartialEq, Eq, Debug)] | 19 | #[derive(Clone, PartialEq, Eq, Debug)] |
19 | pub struct GenericParam { | 20 | pub struct GenericParamData { |
20 | // FIXME: give generic params proper IDs | ||
21 | pub idx: u32, | ||
22 | pub name: Name, | 21 | pub name: Name, |
23 | pub default: Option<TypeRef>, | 22 | pub default: Option<TypeRef>, |
24 | } | 23 | } |
@@ -26,8 +25,7 @@ pub struct GenericParam { | |||
26 | /// Data about the generic parameters of a function, struct, impl, etc. | 25 | /// Data about the generic parameters of a function, struct, impl, etc. |
27 | #[derive(Clone, PartialEq, Eq, Debug)] | 26 | #[derive(Clone, PartialEq, Eq, Debug)] |
28 | pub struct GenericParams { | 27 | pub struct GenericParams { |
29 | pub parent_params: Option<Arc<GenericParams>>, | 28 | pub params: Arena<LocalGenericParamId, GenericParamData>, |
30 | pub params: Vec<GenericParam>, | ||
31 | pub where_predicates: Vec<WherePredicate>, | 29 | pub where_predicates: Vec<WherePredicate>, |
32 | } | 30 | } |
33 | 31 | ||
@@ -46,51 +44,40 @@ impl GenericParams { | |||
46 | db: &impl DefDatabase, | 44 | db: &impl DefDatabase, |
47 | def: GenericDefId, | 45 | def: GenericDefId, |
48 | ) -> Arc<GenericParams> { | 46 | ) -> Arc<GenericParams> { |
49 | let parent_generics = parent_generic_def(db, def).map(|it| db.generic_params(it)); | 47 | Arc::new(GenericParams::new(db, def.into())) |
50 | Arc::new(GenericParams::new(db, def.into(), parent_generics)) | ||
51 | } | 48 | } |
52 | 49 | ||
53 | fn new( | 50 | fn new(db: &impl DefDatabase, def: GenericDefId) -> GenericParams { |
54 | db: &impl DefDatabase, | 51 | let mut generics = GenericParams { params: Arena::default(), where_predicates: Vec::new() }; |
55 | def: GenericDefId, | ||
56 | parent_params: Option<Arc<GenericParams>>, | ||
57 | ) -> GenericParams { | ||
58 | let mut generics = | ||
59 | GenericParams { params: Vec::new(), parent_params, where_predicates: Vec::new() }; | ||
60 | let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; | ||
61 | // FIXME: add `: Sized` bound for everything except for `Self` in traits | 52 | // FIXME: add `: Sized` bound for everything except for `Self` in traits |
62 | match def { | 53 | match def { |
63 | GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), | 54 | GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value), |
64 | GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start), | 55 | GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value), |
65 | GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start), | 56 | GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value), |
66 | GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), | 57 | GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value), |
67 | GenericDefId::TraitId(it) => { | 58 | GenericDefId::TraitId(it) => { |
68 | // traits get the Self type as an implicit first type parameter | 59 | // traits get the Self type as an implicit first type parameter |
69 | generics.params.push(GenericParam { | 60 | generics.params.alloc(GenericParamData { name: name::SELF_TYPE, default: None }); |
70 | idx: start, | 61 | generics.fill(&it.source(db).value); |
71 | name: name::SELF_TYPE, | ||
72 | default: None, | ||
73 | }); | ||
74 | generics.fill(&it.source(db).value, start + 1); | ||
75 | // add super traits as bounds on Self | 62 | // add super traits as bounds on Self |
76 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar | 63 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar |
77 | let self_param = TypeRef::Path(name::SELF_TYPE.into()); | 64 | let self_param = TypeRef::Path(name::SELF_TYPE.into()); |
78 | generics.fill_bounds(&it.source(db).value, self_param); | 65 | generics.fill_bounds(&it.source(db).value, self_param); |
79 | } | 66 | } |
80 | GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start), | 67 | GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value), |
81 | // Note that we don't add `Self` here: in `impl`s, `Self` is not a | 68 | // Note that we don't add `Self` here: in `impl`s, `Self` is not a |
82 | // type-parameter, but rather is a type-alias for impl's target | 69 | // type-parameter, but rather is a type-alias for impl's target |
83 | // type, so this is handled by the resolver. | 70 | // type, so this is handled by the resolver. |
84 | GenericDefId::ImplId(it) => generics.fill(&it.source(db).value, start), | 71 | GenericDefId::ImplId(it) => generics.fill(&it.source(db).value), |
85 | GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} | 72 | GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} |
86 | } | 73 | } |
87 | 74 | ||
88 | generics | 75 | generics |
89 | } | 76 | } |
90 | 77 | ||
91 | fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) { | 78 | fn fill(&mut self, node: &impl TypeParamsOwner) { |
92 | if let Some(params) = node.type_param_list() { | 79 | if let Some(params) = node.type_param_list() { |
93 | self.fill_params(params, start) | 80 | self.fill_params(params) |
94 | } | 81 | } |
95 | if let Some(where_clause) = node.where_clause() { | 82 | if let Some(where_clause) = node.where_clause() { |
96 | self.fill_where_predicates(where_clause); | 83 | self.fill_where_predicates(where_clause); |
@@ -105,13 +92,13 @@ impl GenericParams { | |||
105 | } | 92 | } |
106 | } | 93 | } |
107 | 94 | ||
108 | fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { | 95 | fn fill_params(&mut self, params: ast::TypeParamList) { |
109 | for (idx, type_param) in params.type_params().enumerate() { | 96 | for type_param in params.type_params() { |
110 | let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); | 97 | let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); |
111 | // FIXME: Use `Path::from_src` | 98 | // FIXME: Use `Path::from_src` |
112 | let default = type_param.default_type().map(TypeRef::from_ast); | 99 | let default = type_param.default_type().map(TypeRef::from_ast); |
113 | let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; | 100 | let param = GenericParamData { name: name.clone(), default }; |
114 | self.params.push(param); | 101 | self.params.alloc(param); |
115 | 102 | ||
116 | let type_ref = TypeRef::Path(name.into()); | 103 | let type_ref = TypeRef::Path(name.into()); |
117 | self.fill_bounds(&type_param, type_ref); | 104 | self.fill_bounds(&type_param, type_ref); |
@@ -140,45 +127,7 @@ impl GenericParams { | |||
140 | self.where_predicates.push(WherePredicate { type_ref, bound }); | 127 | self.where_predicates.push(WherePredicate { type_ref, bound }); |
141 | } | 128 | } |
142 | 129 | ||
143 | pub fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { | 130 | pub fn find_by_name(&self, name: &Name) -> Option<LocalGenericParamId> { |
144 | self.params.iter().find(|p| &p.name == name) | 131 | self.params.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None }) |
145 | } | ||
146 | |||
147 | pub fn count_parent_params(&self) -> usize { | ||
148 | self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0) | ||
149 | } | ||
150 | |||
151 | pub fn count_params_including_parent(&self) -> usize { | ||
152 | let parent_count = self.count_parent_params(); | ||
153 | parent_count + self.params.len() | ||
154 | } | ||
155 | |||
156 | fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) { | ||
157 | if let Some(parent) = &self.parent_params { | ||
158 | parent.for_each_param(f); | ||
159 | } | ||
160 | self.params.iter().for_each(f); | ||
161 | } | ||
162 | |||
163 | pub fn params_including_parent(&self) -> Vec<&GenericParam> { | ||
164 | let mut vec = Vec::with_capacity(self.count_params_including_parent()); | ||
165 | self.for_each_param(&mut |p| vec.push(p)); | ||
166 | vec | ||
167 | } | ||
168 | } | ||
169 | |||
170 | fn parent_generic_def(db: &impl DefDatabase, def: GenericDefId) -> Option<GenericDefId> { | ||
171 | let container = match def { | ||
172 | GenericDefId::FunctionId(it) => it.lookup(db).container, | ||
173 | GenericDefId::TypeAliasId(it) => it.lookup(db).container, | ||
174 | GenericDefId::ConstId(it) => it.lookup(db).container, | ||
175 | GenericDefId::EnumVariantId(it) => return Some(it.parent.into()), | ||
176 | GenericDefId::AdtId(_) | GenericDefId::TraitId(_) | GenericDefId::ImplId(_) => return None, | ||
177 | }; | ||
178 | |||
179 | match container { | ||
180 | ContainerId::ImplId(it) => Some(it.into()), | ||
181 | ContainerId::TraitId(it) => Some(it.into()), | ||
182 | ContainerId::ModuleId(_) => None, | ||
183 | } | 132 | } |
184 | } | 133 | } |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 68e66d276..b8dfc0ab1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -318,6 +318,16 @@ macro_rules! impl_froms { | |||
318 | } | 318 | } |
319 | 319 | ||
320 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 320 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
321 | pub struct GenericParamId { | ||
322 | pub parent: GenericDefId, | ||
323 | pub local_id: LocalGenericParamId, | ||
324 | } | ||
325 | |||
326 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
327 | pub struct LocalGenericParamId(RawId); | ||
328 | impl_arena_id!(LocalGenericParamId); | ||
329 | |||
330 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
321 | pub enum ContainerId { | 331 | pub enum ContainerId { |
322 | ModuleId(ModuleId), | 332 | ModuleId(ModuleId), |
323 | ImplId(ImplId), | 333 | ImplId(ImplId), |
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 7d4df222e..e00bd03d5 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs | |||
@@ -18,12 +18,13 @@ use crate::{ | |||
18 | path::{Path, PathKind}, | 18 | path::{Path, PathKind}, |
19 | per_ns::PerNs, | 19 | per_ns::PerNs, |
20 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, | 20 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, |
21 | GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, | 21 | GenericDefId, GenericParamId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, |
22 | StructId, TraitId, TypeAliasId, | 22 | StaticId, StructId, TraitId, TypeAliasId, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | #[derive(Debug, Clone, Default)] | 25 | #[derive(Debug, Clone, Default)] |
26 | pub struct Resolver { | 26 | pub struct Resolver { |
27 | // FIXME: all usages generally call `.rev`, so maybe reverse once in consturciton? | ||
27 | scopes: Vec<Scope>, | 28 | scopes: Vec<Scope>, |
28 | } | 29 | } |
29 | 30 | ||
@@ -58,7 +59,7 @@ enum Scope { | |||
58 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 59 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
59 | pub enum TypeNs { | 60 | pub enum TypeNs { |
60 | SelfType(ImplId), | 61 | SelfType(ImplId), |
61 | GenericParam(u32), | 62 | GenericParam(GenericParamId), |
62 | AdtId(AdtId), | 63 | AdtId(AdtId), |
63 | AdtSelfType(AdtId), | 64 | AdtSelfType(AdtId), |
64 | // Yup, enum variants are added to the types ns, but any usage of variant as | 65 | // Yup, enum variants are added to the types ns, but any usage of variant as |
@@ -152,10 +153,13 @@ impl Resolver { | |||
152 | Scope::ExprScope(_) => continue, | 153 | Scope::ExprScope(_) => continue, |
153 | Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, | 154 | Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, |
154 | 155 | ||
155 | Scope::GenericParams { params, .. } => { | 156 | Scope::GenericParams { params, def } => { |
156 | if let Some(param) = params.find_by_name(first_name) { | 157 | if let Some(local_id) = params.find_by_name(first_name) { |
157 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 158 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; |
158 | return Some((TypeNs::GenericParam(param.idx), idx)); | 159 | return Some(( |
160 | TypeNs::GenericParam(GenericParamId { local_id, parent: *def }), | ||
161 | idx, | ||
162 | )); | ||
159 | } | 163 | } |
160 | } | 164 | } |
161 | Scope::ImplBlockScope(impl_) => { | 165 | Scope::ImplBlockScope(impl_) => { |
@@ -246,9 +250,9 @@ impl Resolver { | |||
246 | } | 250 | } |
247 | Scope::ExprScope(_) => continue, | 251 | Scope::ExprScope(_) => continue, |
248 | 252 | ||
249 | Scope::GenericParams { params, .. } if n_segments > 1 => { | 253 | Scope::GenericParams { params, def } if n_segments > 1 => { |
250 | if let Some(param) = params.find_by_name(first_name) { | 254 | if let Some(local_id) = params.find_by_name(first_name) { |
251 | let ty = TypeNs::GenericParam(param.idx); | 255 | let ty = TypeNs::GenericParam(GenericParamId { local_id, parent: *def }); |
252 | return Some(ResolveValueResult::Partial(ty, 1)); | 256 | return Some(ResolveValueResult::Partial(ty, 1)); |
253 | } | 257 | } |
254 | } | 258 | } |
@@ -368,6 +372,7 @@ impl Resolver { | |||
368 | ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { | 372 | ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { |
369 | self.scopes | 373 | self.scopes |
370 | .iter() | 374 | .iter() |
375 | .rev() | ||
371 | .filter_map(|scope| match scope { | 376 | .filter_map(|scope| match scope { |
372 | Scope::GenericParams { params, .. } => Some(params), | 377 | Scope::GenericParams { params, .. } => Some(params), |
373 | _ => None, | 378 | _ => None, |
@@ -376,14 +381,14 @@ impl Resolver { | |||
376 | } | 381 | } |
377 | 382 | ||
378 | pub fn generic_def(&self) -> Option<GenericDefId> { | 383 | pub fn generic_def(&self) -> Option<GenericDefId> { |
379 | self.scopes.iter().find_map(|scope| match scope { | 384 | self.scopes.iter().rev().find_map(|scope| match scope { |
380 | Scope::GenericParams { def, .. } => Some(*def), | 385 | Scope::GenericParams { def, .. } => Some(*def), |
381 | _ => None, | 386 | _ => None, |
382 | }) | 387 | }) |
383 | } | 388 | } |
384 | 389 | ||
385 | pub fn body_owner(&self) -> Option<DefWithBodyId> { | 390 | pub fn body_owner(&self) -> Option<DefWithBodyId> { |
386 | self.scopes.iter().find_map(|scope| match scope { | 391 | self.scopes.iter().rev().find_map(|scope| match scope { |
387 | Scope::ExprScope(it) => Some(it.owner), | 392 | Scope::ExprScope(it) => Some(it.owner), |
388 | _ => None, | 393 | _ => None, |
389 | }) | 394 | }) |
@@ -394,7 +399,7 @@ pub enum ScopeDef { | |||
394 | PerNs(PerNs), | 399 | PerNs(PerNs), |
395 | ImplSelfType(ImplId), | 400 | ImplSelfType(ImplId), |
396 | AdtSelfType(AdtId), | 401 | AdtSelfType(AdtId), |
397 | GenericParam(u32), | 402 | GenericParam(GenericParamId), |
398 | Local(PatId), | 403 | Local(PatId), |
399 | } | 404 | } |
400 | 405 | ||
@@ -425,9 +430,12 @@ impl Scope { | |||
425 | }); | 430 | }); |
426 | } | 431 | } |
427 | } | 432 | } |
428 | Scope::GenericParams { params, .. } => { | 433 | Scope::GenericParams { params, def } => { |
429 | for param in params.params.iter() { | 434 | for (local_id, param) in params.params.iter() { |
430 | f(param.name.clone(), ScopeDef::GenericParam(param.idx)) | 435 | f( |
436 | param.name.clone(), | ||
437 | ScopeDef::GenericParam(GenericParamId { local_id, parent: *def }), | ||
438 | ) | ||
431 | } | 439 | } |
432 | } | 440 | } |
433 | Scope::ImplBlockScope(i) => { | 441 | Scope::ImplBlockScope(i) => { |
diff --git a/crates/ra_hir_ty/src/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs index 9d1d4e48c..d557962b4 100644 --- a/crates/ra_hir_ty/src/autoderef.rs +++ b/crates/ra_hir_ty/src/autoderef.rs | |||
@@ -10,10 +10,10 @@ use hir_expand::name; | |||
10 | use log::{info, warn}; | 10 | use log::{info, warn}; |
11 | use ra_db::CrateId; | 11 | use ra_db::CrateId; |
12 | 12 | ||
13 | use crate::db::HirDatabase; | 13 | use crate::{ |
14 | 14 | db::HirDatabase, | |
15 | use super::{ | ||
16 | traits::{InEnvironment, Solution}, | 15 | traits::{InEnvironment, Solution}, |
16 | utils::generics, | ||
17 | Canonical, Substs, Ty, TypeWalk, | 17 | Canonical, Substs, Ty, TypeWalk, |
18 | }; | 18 | }; |
19 | 19 | ||
@@ -54,8 +54,8 @@ fn deref_by_trait( | |||
54 | }; | 54 | }; |
55 | let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?; | 55 | let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?; |
56 | 56 | ||
57 | let generic_params = db.generic_params(target.into()); | 57 | let generic_params = generics(db, target.into()); |
58 | if generic_params.count_params_including_parent() != 1 { | 58 | if generic_params.len() != 1 { |
59 | // the Target type + Deref trait should only have one generic parameter, | 59 | // the Target type + Deref trait should only have one generic parameter, |
60 | // namely Deref's Self type | 60 | // namely Deref's Self type |
61 | return None; | 61 | return None; |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index b8df27706..2c296987c 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -6,7 +6,6 @@ use std::sync::Arc; | |||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | builtin_type::Signedness, | 7 | builtin_type::Signedness, |
8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
9 | generics::GenericParams, | ||
10 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
11 | resolver::resolver_for_expr, | 10 | resolver::resolver_for_expr, |
12 | AdtId, ContainerId, Lookup, StructFieldId, | 11 | AdtId, ContainerId, Lookup, StructFieldId, |
@@ -15,7 +14,11 @@ use hir_expand::name::{self, Name}; | |||
15 | use ra_syntax::ast::RangeOp; | 14 | use ra_syntax::ast::RangeOp; |
16 | 15 | ||
17 | use crate::{ | 16 | use crate::{ |
18 | autoderef, db::HirDatabase, method_resolution, op, traits::InEnvironment, utils::variant_data, | 17 | autoderef, |
18 | db::HirDatabase, | ||
19 | method_resolution, op, | ||
20 | traits::InEnvironment, | ||
21 | utils::{generics, variant_data, Generics}, | ||
19 | CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, | 22 | CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, |
20 | TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, | 23 | TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, |
21 | }; | 24 | }; |
@@ -596,7 +599,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
596 | Some((ty, func)) => { | 599 | Some((ty, func)) => { |
597 | let ty = canonicalized_receiver.decanonicalize_ty(ty); | 600 | let ty = canonicalized_receiver.decanonicalize_ty(ty); |
598 | self.write_method_resolution(tgt_expr, func); | 601 | self.write_method_resolution(tgt_expr, func); |
599 | (ty, self.db.value_ty(func.into()), Some(self.db.generic_params(func.into()))) | 602 | (ty, self.db.value_ty(func.into()), Some(generics(self.db, func.into()))) |
600 | } | 603 | } |
601 | None => (receiver_ty, Ty::Unknown, None), | 604 | None => (receiver_ty, Ty::Unknown, None), |
602 | }; | 605 | }; |
@@ -653,16 +656,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
653 | 656 | ||
654 | fn substs_for_method_call( | 657 | fn substs_for_method_call( |
655 | &mut self, | 658 | &mut self, |
656 | def_generics: Option<Arc<GenericParams>>, | 659 | def_generics: Option<Generics>, |
657 | generic_args: Option<&GenericArgs>, | 660 | generic_args: Option<&GenericArgs>, |
658 | receiver_ty: &Ty, | 661 | receiver_ty: &Ty, |
659 | ) -> Substs { | 662 | ) -> Substs { |
660 | let (parent_param_count, param_count) = | 663 | let (total_len, _parent_len, child_len) = |
661 | def_generics.as_ref().map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); | 664 | def_generics.as_ref().map_or((0, 0, 0), |g| g.len_split()); |
662 | let mut substs = Vec::with_capacity(parent_param_count + param_count); | 665 | let mut substs = Vec::with_capacity(total_len); |
663 | // Parent arguments are unknown, except for the receiver type | 666 | // Parent arguments are unknown, except for the receiver type |
664 | if let Some(parent_generics) = def_generics.and_then(|p| p.parent_params.clone()) { | 667 | if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { |
665 | for param in &parent_generics.params { | 668 | for (_id, param) in parent_generics { |
666 | if param.name == name::SELF_TYPE { | 669 | if param.name == name::SELF_TYPE { |
667 | substs.push(receiver_ty.clone()); | 670 | substs.push(receiver_ty.clone()); |
668 | } else { | 671 | } else { |
@@ -673,7 +676,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
673 | // handle provided type arguments | 676 | // handle provided type arguments |
674 | if let Some(generic_args) = generic_args { | 677 | if let Some(generic_args) = generic_args { |
675 | // if args are provided, it should be all of them, but we can't rely on that | 678 | // if args are provided, it should be all of them, but we can't rely on that |
676 | for arg in generic_args.args.iter().take(param_count) { | 679 | for arg in generic_args.args.iter().take(child_len) { |
677 | match arg { | 680 | match arg { |
678 | GenericArg::Type(type_ref) => { | 681 | GenericArg::Type(type_ref) => { |
679 | let ty = self.make_ty(type_ref); | 682 | let ty = self.make_ty(type_ref); |
@@ -683,10 +686,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
683 | } | 686 | } |
684 | }; | 687 | }; |
685 | let supplied_params = substs.len(); | 688 | let supplied_params = substs.len(); |
686 | for _ in supplied_params..parent_param_count + param_count { | 689 | for _ in supplied_params..total_len { |
687 | substs.push(Ty::Unknown); | 690 | substs.push(Ty::Unknown); |
688 | } | 691 | } |
689 | assert_eq!(substs.len(), parent_param_count + param_count); | 692 | assert_eq!(substs.len(), total_len); |
690 | Substs(substs.into()) | 693 | Substs(substs.into()) |
691 | } | 694 | } |
692 | 695 | ||
@@ -705,11 +708,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
705 | CallableDef::FunctionId(f) => { | 708 | CallableDef::FunctionId(f) => { |
706 | if let ContainerId::TraitId(trait_) = f.lookup(self.db).container { | 709 | if let ContainerId::TraitId(trait_) = f.lookup(self.db).container { |
707 | // construct a TraitDef | 710 | // construct a TraitDef |
708 | let substs = a_ty.parameters.prefix( | 711 | let substs = |
709 | self.db | 712 | a_ty.parameters.prefix(generics(self.db, trait_.into()).len()); |
710 | .generic_params(trait_.into()) | ||
711 | .count_params_including_parent(), | ||
712 | ); | ||
713 | self.obligations.push(Obligation::Trait(TraitRef { | 713 | self.obligations.push(Obligation::Trait(TraitRef { |
714 | trait_: trait_.into(), | 714 | trait_: trait_.into(), |
715 | substs, | 715 | substs, |
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 3c1f738df..3ad913e55 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -44,8 +44,8 @@ use std::sync::Arc; | |||
44 | use std::{fmt, iter, mem}; | 44 | use std::{fmt, iter, mem}; |
45 | 45 | ||
46 | use hir_def::{ | 46 | use hir_def::{ |
47 | expr::ExprId, generics::GenericParams, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId, | 47 | expr::ExprId, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, |
48 | GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, | 48 | Lookup, TraitId, TypeAliasId, |
49 | }; | 49 | }; |
50 | use hir_expand::name::Name; | 50 | use hir_expand::name::Name; |
51 | use ra_db::{impl_intern_key, salsa, CrateId}; | 51 | use ra_db::{impl_intern_key, salsa, CrateId}; |
@@ -53,7 +53,7 @@ use ra_db::{impl_intern_key, salsa, CrateId}; | |||
53 | use crate::{ | 53 | use crate::{ |
54 | db::HirDatabase, | 54 | db::HirDatabase, |
55 | primitive::{FloatTy, IntTy, Uncertain}, | 55 | primitive::{FloatTy, IntTy, Uncertain}, |
56 | utils::make_mut_slice, | 56 | utils::{generics, make_mut_slice, Generics}, |
57 | }; | 57 | }; |
58 | use display::{HirDisplay, HirFormatter}; | 58 | use display::{HirDisplay, HirFormatter}; |
59 | 59 | ||
@@ -166,16 +166,16 @@ impl TypeCtor { | |||
166 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure | 166 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure |
167 | => 1, | 167 | => 1, |
168 | TypeCtor::Adt(adt) => { | 168 | TypeCtor::Adt(adt) => { |
169 | let generic_params = db.generic_params(AdtId::from(adt).into()); | 169 | let generic_params = generics(db, AdtId::from(adt).into()); |
170 | generic_params.count_params_including_parent() | 170 | generic_params.len() |
171 | } | 171 | } |
172 | TypeCtor::FnDef(callable) => { | 172 | TypeCtor::FnDef(callable) => { |
173 | let generic_params = db.generic_params(callable.into()); | 173 | let generic_params = generics(db, callable.into()); |
174 | generic_params.count_params_including_parent() | 174 | generic_params.len() |
175 | } | 175 | } |
176 | TypeCtor::AssociatedType(type_alias) => { | 176 | TypeCtor::AssociatedType(type_alias) => { |
177 | let generic_params = db.generic_params(type_alias.into()); | 177 | let generic_params = generics(db, type_alias.into()); |
178 | generic_params.count_params_including_parent() | 178 | generic_params.len() |
179 | } | 179 | } |
180 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, | 180 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, |
181 | TypeCtor::Tuple { cardinality } => cardinality as usize, | 181 | TypeCtor::Tuple { cardinality } => cardinality as usize, |
@@ -364,36 +364,26 @@ impl Substs { | |||
364 | } | 364 | } |
365 | 365 | ||
366 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 366 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
367 | pub fn identity(generic_params: &GenericParams) -> Substs { | 367 | pub(crate) fn identity(generic_params: &Generics) -> Substs { |
368 | Substs( | 368 | Substs( |
369 | generic_params | 369 | generic_params.iter().map(|(idx, p)| Ty::Param { idx, name: p.name.clone() }).collect(), |
370 | .params_including_parent() | ||
371 | .into_iter() | ||
372 | .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() }) | ||
373 | .collect(), | ||
374 | ) | 370 | ) |
375 | } | 371 | } |
376 | 372 | ||
377 | /// Return Substs that replace each parameter by a bound variable. | 373 | /// Return Substs that replace each parameter by a bound variable. |
378 | pub fn bound_vars(generic_params: &GenericParams) -> Substs { | 374 | pub(crate) fn bound_vars(generic_params: &Generics) -> Substs { |
379 | Substs( | 375 | Substs(generic_params.iter().map(|(idx, _p)| Ty::Bound(idx)).collect()) |
380 | generic_params | ||
381 | .params_including_parent() | ||
382 | .into_iter() | ||
383 | .map(|p| Ty::Bound(p.idx)) | ||
384 | .collect(), | ||
385 | ) | ||
386 | } | 376 | } |
387 | 377 | ||
388 | pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { | 378 | pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { |
389 | let def = def.into(); | 379 | let def = def.into(); |
390 | let params = db.generic_params(def); | 380 | let params = generics(db, def); |
391 | let param_count = params.count_params_including_parent(); | 381 | let param_count = params.len(); |
392 | Substs::builder(param_count) | 382 | Substs::builder(param_count) |
393 | } | 383 | } |
394 | 384 | ||
395 | pub fn build_for_generics(generic_params: &GenericParams) -> SubstsBuilder { | 385 | pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder { |
396 | Substs::builder(generic_params.count_params_including_parent()) | 386 | Substs::builder(generic_params.len()) |
397 | } | 387 | } |
398 | 388 | ||
399 | pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { | 389 | pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { |
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 32569ac66..eab91229e 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -24,7 +24,7 @@ use crate::{ | |||
24 | db::HirDatabase, | 24 | db::HirDatabase, |
25 | primitive::{FloatTy, IntTy}, | 25 | primitive::{FloatTy, IntTy}, |
26 | utils::{ | 26 | utils::{ |
27 | all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice, | 27 | all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice, |
28 | variant_data, | 28 | variant_data, |
29 | }, | 29 | }, |
30 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, | 30 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, |
@@ -111,7 +111,9 @@ impl Ty { | |||
111 | Some((it, None)) => it, | 111 | Some((it, None)) => it, |
112 | _ => return None, | 112 | _ => return None, |
113 | }; | 113 | }; |
114 | if let TypeNs::GenericParam(idx) = resolution { | 114 | if let TypeNs::GenericParam(param_id) = resolution { |
115 | let generics = generics(db, resolver.generic_def().expect("generics in scope")); | ||
116 | let idx = generics.param_idx(param_id); | ||
115 | Some(idx) | 117 | Some(idx) |
116 | } else { | 118 | } else { |
117 | None | 119 | None |
@@ -174,9 +176,11 @@ impl Ty { | |||
174 | Ty::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) | 176 | Ty::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) |
175 | }; | 177 | }; |
176 | } | 178 | } |
177 | TypeNs::GenericParam(idx) => { | 179 | TypeNs::GenericParam(param_id) => { |
180 | let generics = generics(db, resolver.generic_def().expect("generics in scope")); | ||
181 | let idx = generics.param_idx(param_id); | ||
178 | // FIXME: maybe return name in resolution? | 182 | // FIXME: maybe return name in resolution? |
179 | let name = resolved_segment.name.clone(); | 183 | let name = generics.param_name(param_id); |
180 | Ty::Param { idx, name } | 184 | Ty::Param { idx, name } |
181 | } | 185 | } |
182 | TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), | 186 | TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), |
@@ -315,11 +319,10 @@ pub(super) fn substs_from_path_segment( | |||
315 | add_self_param: bool, | 319 | add_self_param: bool, |
316 | ) -> Substs { | 320 | ) -> Substs { |
317 | let mut substs = Vec::new(); | 321 | let mut substs = Vec::new(); |
318 | let def_generics = def_generic.map(|def| db.generic_params(def.into())); | 322 | let def_generics = def_generic.map(|def| generics(db, def.into())); |
319 | 323 | ||
320 | let (parent_param_count, param_count) = | 324 | let (total_len, parent_len, child_len) = def_generics.map_or((0, 0, 0), |g| g.len_split()); |
321 | def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); | 325 | substs.extend(iter::repeat(Ty::Unknown).take(parent_len)); |
322 | substs.extend(iter::repeat(Ty::Unknown).take(parent_param_count)); | ||
323 | if add_self_param { | 326 | if add_self_param { |
324 | // FIXME this add_self_param argument is kind of a hack: Traits have the | 327 | // FIXME this add_self_param argument is kind of a hack: Traits have the |
325 | // Self type as an implicit first type parameter, but it can't be | 328 | // Self type as an implicit first type parameter, but it can't be |
@@ -330,8 +333,8 @@ pub(super) fn substs_from_path_segment( | |||
330 | if let Some(generic_args) = &segment.args_and_bindings { | 333 | if let Some(generic_args) = &segment.args_and_bindings { |
331 | // if args are provided, it should be all of them, but we can't rely on that | 334 | // if args are provided, it should be all of them, but we can't rely on that |
332 | let self_param_correction = if add_self_param { 1 } else { 0 }; | 335 | let self_param_correction = if add_self_param { 1 } else { 0 }; |
333 | let param_count = param_count - self_param_correction; | 336 | let child_len = child_len + self_param_correction; |
334 | for arg in generic_args.args.iter().take(param_count) { | 337 | for arg in generic_args.args.iter().take(child_len) { |
335 | match arg { | 338 | match arg { |
336 | GenericArg::Type(type_ref) => { | 339 | GenericArg::Type(type_ref) => { |
337 | let ty = Ty::from_hir(db, resolver, type_ref); | 340 | let ty = Ty::from_hir(db, resolver, type_ref); |
@@ -342,10 +345,10 @@ pub(super) fn substs_from_path_segment( | |||
342 | } | 345 | } |
343 | // add placeholders for args that were not provided | 346 | // add placeholders for args that were not provided |
344 | let supplied_params = substs.len(); | 347 | let supplied_params = substs.len(); |
345 | for _ in supplied_params..parent_param_count + param_count { | 348 | for _ in supplied_params..total_len { |
346 | substs.push(Ty::Unknown); | 349 | substs.push(Ty::Unknown); |
347 | } | 350 | } |
348 | assert_eq!(substs.len(), parent_param_count + param_count); | 351 | assert_eq!(substs.len(), total_len); |
349 | 352 | ||
350 | // handle defaults | 353 | // handle defaults |
351 | if let Some(def_generic) = def_generic { | 354 | if let Some(def_generic) = def_generic { |
@@ -567,12 +570,11 @@ pub(crate) fn generic_predicates_query( | |||
567 | /// Resolve the default type params from generics | 570 | /// Resolve the default type params from generics |
568 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { | 571 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { |
569 | let resolver = def.resolver(db); | 572 | let resolver = def.resolver(db); |
570 | let generic_params = db.generic_params(def.into()); | 573 | let generic_params = generics(db, def.into()); |
571 | 574 | ||
572 | let defaults = generic_params | 575 | let defaults = generic_params |
573 | .params_including_parent() | 576 | .iter() |
574 | .into_iter() | 577 | .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) |
575 | .map(|p| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) | ||
576 | .collect(); | 578 | .collect(); |
577 | 579 | ||
578 | Substs(defaults) | 580 | Substs(defaults) |
@@ -589,7 +591,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { | |||
589 | /// Build the declared type of a function. This should not need to look at the | 591 | /// Build the declared type of a function. This should not need to look at the |
590 | /// function body. | 592 | /// function body. |
591 | fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { | 593 | fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { |
592 | let generics = db.generic_params(def.into()); | 594 | let generics = generics(db, def.into()); |
593 | let substs = Substs::identity(&generics); | 595 | let substs = Substs::identity(&generics); |
594 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 596 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
595 | } | 597 | } |
@@ -639,7 +641,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { | |||
639 | if struct_data.variant_data.is_unit() { | 641 | if struct_data.variant_data.is_unit() { |
640 | return type_for_adt(db, def.into()); // Unit struct | 642 | return type_for_adt(db, def.into()); // Unit struct |
641 | } | 643 | } |
642 | let generics = db.generic_params(def.into()); | 644 | let generics = generics(db, def.into()); |
643 | let substs = Substs::identity(&generics); | 645 | let substs = Substs::identity(&generics); |
644 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 646 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
645 | } | 647 | } |
@@ -653,7 +655,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId | |||
653 | .iter() | 655 | .iter() |
654 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 656 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
655 | .collect::<Vec<_>>(); | 657 | .collect::<Vec<_>>(); |
656 | let generics = db.generic_params(def.parent.into()); | 658 | let generics = generics(db, def.parent.into()); |
657 | let substs = Substs::identity(&generics); | 659 | let substs = Substs::identity(&generics); |
658 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); | 660 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); |
659 | FnSig::from_params_and_return(params, ret) | 661 | FnSig::from_params_and_return(params, ret) |
@@ -666,18 +668,18 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) | |||
666 | if var_data.is_unit() { | 668 | if var_data.is_unit() { |
667 | return type_for_adt(db, def.parent.into()); // Unit variant | 669 | return type_for_adt(db, def.parent.into()); // Unit variant |
668 | } | 670 | } |
669 | let generics = db.generic_params(def.parent.into()); | 671 | let generics = generics(db, def.parent.into()); |
670 | let substs = Substs::identity(&generics); | 672 | let substs = Substs::identity(&generics); |
671 | Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) | 673 | Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) |
672 | } | 674 | } |
673 | 675 | ||
674 | fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { | 676 | fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { |
675 | let generics = db.generic_params(adt.into()); | 677 | let generics = generics(db, adt.into()); |
676 | Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) | 678 | Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) |
677 | } | 679 | } |
678 | 680 | ||
679 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { | 681 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { |
680 | let generics = db.generic_params(t.into()); | 682 | let generics = generics(db, t.into()); |
681 | let resolver = t.resolver(db); | 683 | let resolver = t.resolver(db); |
682 | let type_ref = &db.type_alias_data(t).type_ref; | 684 | let type_ref = &db.type_alias_data(t).type_ref; |
683 | let substs = Substs::identity(&generics); | 685 | let substs = Substs::identity(&generics); |
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index e3f02fa15..1e7ff93d5 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -19,8 +19,8 @@ use ra_db::{ | |||
19 | 19 | ||
20 | use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; | 20 | use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; |
21 | use crate::{ | 21 | use crate::{ |
22 | db::HirDatabase, display::HirDisplay, ApplicationTy, GenericPredicate, ProjectionTy, Substs, | 22 | db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate, |
23 | TraitRef, Ty, TypeCtor, TypeWalk, | 23 | ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | /// This represents a trait whose name we could not resolve. | 26 | /// This represents a trait whose name we could not resolve. |
@@ -547,7 +547,7 @@ pub(crate) fn associated_ty_data_query( | |||
547 | ContainerId::TraitId(t) => t, | 547 | ContainerId::TraitId(t) => t, |
548 | _ => panic!("associated type not in trait"), | 548 | _ => panic!("associated type not in trait"), |
549 | }; | 549 | }; |
550 | let generic_params = db.generic_params(type_alias.into()); | 550 | let generic_params = generics(db, type_alias.into()); |
551 | let bound_data = chalk_rust_ir::AssociatedTyDatumBound { | 551 | let bound_data = chalk_rust_ir::AssociatedTyDatumBound { |
552 | // FIXME add bounds and where clauses | 552 | // FIXME add bounds and where clauses |
553 | bounds: vec![], | 553 | bounds: vec![], |
@@ -557,7 +557,7 @@ pub(crate) fn associated_ty_data_query( | |||
557 | trait_id: trait_.to_chalk(db), | 557 | trait_id: trait_.to_chalk(db), |
558 | id, | 558 | id, |
559 | name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), | 559 | name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), |
560 | binders: make_binders(bound_data, generic_params.count_params_including_parent()), | 560 | binders: make_binders(bound_data, generic_params.len()), |
561 | }; | 561 | }; |
562 | Arc::new(datum) | 562 | Arc::new(datum) |
563 | } | 563 | } |
@@ -589,7 +589,7 @@ pub(crate) fn trait_datum_query( | |||
589 | let trait_: TraitId = from_chalk(db, trait_id); | 589 | let trait_: TraitId = from_chalk(db, trait_id); |
590 | let trait_data = db.trait_data(trait_); | 590 | let trait_data = db.trait_data(trait_); |
591 | debug!("trait {:?} = {:?}", trait_id, trait_data.name); | 591 | debug!("trait {:?} = {:?}", trait_id, trait_data.name); |
592 | let generic_params = db.generic_params(trait_.into()); | 592 | let generic_params = generics(db, trait_.into()); |
593 | let bound_vars = Substs::bound_vars(&generic_params); | 593 | let bound_vars = Substs::bound_vars(&generic_params); |
594 | let flags = chalk_rust_ir::TraitFlags { | 594 | let flags = chalk_rust_ir::TraitFlags { |
595 | auto: trait_data.auto, | 595 | auto: trait_data.auto, |
@@ -626,7 +626,7 @@ pub(crate) fn struct_datum_query( | |||
626 | let where_clauses = type_ctor | 626 | let where_clauses = type_ctor |
627 | .as_generic_def() | 627 | .as_generic_def() |
628 | .map(|generic_def| { | 628 | .map(|generic_def| { |
629 | let generic_params = db.generic_params(generic_def.into()); | 629 | let generic_params = generics(db, generic_def.into()); |
630 | let bound_vars = Substs::bound_vars(&generic_params); | 630 | let bound_vars = Substs::bound_vars(&generic_params); |
631 | convert_where_clauses(db, generic_def, &bound_vars) | 631 | convert_where_clauses(db, generic_def, &bound_vars) |
632 | }) | 632 | }) |
@@ -669,7 +669,7 @@ fn impl_block_datum( | |||
669 | let trait_ref = db.impl_trait(impl_id)?; | 669 | let trait_ref = db.impl_trait(impl_id)?; |
670 | let impl_data = db.impl_data(impl_id); | 670 | let impl_data = db.impl_data(impl_id); |
671 | 671 | ||
672 | let generic_params = db.generic_params(impl_id.into()); | 672 | let generic_params = generics(db, impl_id.into()); |
673 | let bound_vars = Substs::bound_vars(&generic_params); | 673 | let bound_vars = Substs::bound_vars(&generic_params); |
674 | let trait_ref = trait_ref.subst(&bound_vars); | 674 | let trait_ref = trait_ref.subst(&bound_vars); |
675 | let trait_ = trait_ref.trait_; | 675 | let trait_ = trait_ref.trait_; |
@@ -767,7 +767,7 @@ fn type_alias_associated_ty_value( | |||
767 | .trait_data(trait_ref.trait_) | 767 | .trait_data(trait_ref.trait_) |
768 | .associated_type_by_name(&type_alias_data.name) | 768 | .associated_type_by_name(&type_alias_data.name) |
769 | .expect("assoc ty value should not exist"); // validated when building the impl data as well | 769 | .expect("assoc ty value should not exist"); // validated when building the impl data as well |
770 | let generic_params = db.generic_params(impl_id.into()); | 770 | let generic_params = generics(db, impl_id.into()); |
771 | let bound_vars = Substs::bound_vars(&generic_params); | 771 | let bound_vars = Substs::bound_vars(&generic_params); |
772 | let ty = db.ty(type_alias.into()).subst(&bound_vars); | 772 | let ty = db.ty(type_alias.into()).subst(&bound_vars); |
773 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; | 773 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; |
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index e4ba890ef..936cfe25e 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs | |||
@@ -5,9 +5,10 @@ use std::sync::Arc; | |||
5 | use hir_def::{ | 5 | use hir_def::{ |
6 | adt::VariantData, | 6 | adt::VariantData, |
7 | db::DefDatabase, | 7 | db::DefDatabase, |
8 | generics::{GenericParamData, GenericParams}, | ||
8 | resolver::{HasResolver, TypeNs}, | 9 | resolver::{HasResolver, TypeNs}, |
9 | type_ref::TypeRef, | 10 | type_ref::TypeRef, |
10 | TraitId, TypeAliasId, VariantId, | 11 | ContainerId, GenericDefId, GenericParamId, Lookup, TraitId, TypeAliasId, VariantId, |
11 | }; | 12 | }; |
12 | use hir_expand::name::{self, Name}; | 13 | use hir_expand::name::{self, Name}; |
13 | 14 | ||
@@ -82,3 +83,83 @@ pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] { | |||
82 | } | 83 | } |
83 | Arc::get_mut(a).unwrap() | 84 | Arc::get_mut(a).unwrap() |
84 | } | 85 | } |
86 | |||
87 | pub(crate) fn generics(db: &impl DefDatabase, def: GenericDefId) -> Generics { | ||
88 | let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def))); | ||
89 | Generics { def, params: db.generic_params(def), parent_generics } | ||
90 | } | ||
91 | |||
92 | pub(crate) struct Generics { | ||
93 | def: GenericDefId, | ||
94 | pub(crate) params: Arc<GenericParams>, | ||
95 | parent_generics: Option<Box<Generics>>, | ||
96 | } | ||
97 | |||
98 | impl Generics { | ||
99 | pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = (u32, &'a GenericParamData)> + 'a { | ||
100 | self.parent_generics | ||
101 | .as_ref() | ||
102 | .into_iter() | ||
103 | .flat_map(|it| it.params.params.iter()) | ||
104 | .chain(self.params.params.iter()) | ||
105 | .enumerate() | ||
106 | .map(|(i, (_local_id, p))| (i as u32, p)) | ||
107 | } | ||
108 | |||
109 | pub(crate) fn iter_parent<'a>( | ||
110 | &'a self, | ||
111 | ) -> impl Iterator<Item = (u32, &'a GenericParamData)> + 'a { | ||
112 | self.parent_generics | ||
113 | .as_ref() | ||
114 | .into_iter() | ||
115 | .flat_map(|it| it.params.params.iter()) | ||
116 | .enumerate() | ||
117 | .map(|(i, (_local_id, p))| (i as u32, p)) | ||
118 | } | ||
119 | |||
120 | pub(crate) fn len(&self) -> usize { | ||
121 | self.len_split().0 | ||
122 | } | ||
123 | /// (total, parents, child) | ||
124 | pub(crate) fn len_split(&self) -> (usize, usize, usize) { | ||
125 | let parent = self.parent_generics.as_ref().map_or(0, |p| p.len()); | ||
126 | let child = self.params.params.len(); | ||
127 | (parent + child, parent, child) | ||
128 | } | ||
129 | pub(crate) fn param_idx(&self, param: GenericParamId) -> u32 { | ||
130 | self.find_param(param).0 | ||
131 | } | ||
132 | pub(crate) fn param_name(&self, param: GenericParamId) -> Name { | ||
133 | self.find_param(param).1.name.clone() | ||
134 | } | ||
135 | fn find_param(&self, param: GenericParamId) -> (u32, &GenericParamData) { | ||
136 | if param.parent == self.def { | ||
137 | let (idx, (_local_id, data)) = self | ||
138 | .params | ||
139 | .params | ||
140 | .iter() | ||
141 | .enumerate() | ||
142 | .find(|(_, (idx, _))| *idx == param.local_id) | ||
143 | .unwrap(); | ||
144 | let (_total, parent_len, _child) = self.len_split(); | ||
145 | return ((parent_len + idx) as u32, data); | ||
146 | } | ||
147 | self.parent_generics.as_ref().unwrap().find_param(param) | ||
148 | } | ||
149 | } | ||
150 | |||
151 | fn parent_generic_def(db: &impl DefDatabase, def: GenericDefId) -> Option<GenericDefId> { | ||
152 | let container = match def { | ||
153 | GenericDefId::FunctionId(it) => it.lookup(db).container, | ||
154 | GenericDefId::TypeAliasId(it) => it.lookup(db).container, | ||
155 | GenericDefId::ConstId(it) => it.lookup(db).container, | ||
156 | GenericDefId::EnumVariantId(it) => return Some(it.parent.into()), | ||
157 | GenericDefId::AdtId(_) | GenericDefId::TraitId(_) | GenericDefId::ImplId(_) => return None, | ||
158 | }; | ||
159 | |||
160 | match container { | ||
161 | ContainerId::ImplId(it) => Some(it.into()), | ||
162 | ContainerId::TraitId(it) => Some(it.into()), | ||
163 | ContainerId::ModuleId(_) => None, | ||
164 | } | ||
165 | } | ||