diff options
author | Seivan Heidari <[email protected]> | 2019-11-21 00:11:41 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-11-21 00:11:41 +0000 |
commit | 358a1bcd708c622836723e5201b6de77cc9ff327 (patch) | |
tree | aeff9c96a6059fa2b02e7c87ec88753bc7993d8d /crates/ra_hir_def/src | |
parent | 1e2d090ab8a9bda18f148b894b7948eb05b976e6 (diff) | |
parent | 612a72fc4ea4376920f2a7da7b3c334227c1716c (diff) |
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/scope.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir_def/src/diagnostics.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/generics.rs | 185 | ||||
-rw-r--r-- | crates/ra_hir_def/src/impls.rs (renamed from crates/ra_hir_def/src/imp.rs) | 35 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 180 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/traits.rs | 59 |
13 files changed, 498 insertions, 59 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index a29c4d41e..d04f54e15 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -54,8 +54,8 @@ impl StructData { | |||
54 | id: StructOrUnionId, | 54 | id: StructOrUnionId, |
55 | ) -> Arc<StructData> { | 55 | ) -> Arc<StructData> { |
56 | let src = id.source(db); | 56 | let src = id.source(db); |
57 | let name = src.ast.name().map(|n| n.as_name()); | 57 | let name = src.value.name().map(|n| n.as_name()); |
58 | let variant_data = VariantData::new(src.ast.kind()); | 58 | let variant_data = VariantData::new(src.value.kind()); |
59 | let variant_data = Arc::new(variant_data); | 59 | let variant_data = Arc::new(variant_data); |
60 | Arc::new(StructData { name, variant_data }) | 60 | Arc::new(StructData { name, variant_data }) |
61 | } | 61 | } |
@@ -64,9 +64,9 @@ impl StructData { | |||
64 | impl EnumData { | 64 | impl EnumData { |
65 | pub(crate) fn enum_data_query(db: &impl DefDatabase2, e: EnumId) -> Arc<EnumData> { | 65 | pub(crate) fn enum_data_query(db: &impl DefDatabase2, e: EnumId) -> Arc<EnumData> { |
66 | let src = e.source(db); | 66 | let src = e.source(db); |
67 | let name = src.ast.name().map(|n| n.as_name()); | 67 | let name = src.value.name().map(|n| n.as_name()); |
68 | let variants = src | 68 | let variants = src |
69 | .ast | 69 | .value |
70 | .variant_list() | 70 | .variant_list() |
71 | .into_iter() | 71 | .into_iter() |
72 | .flat_map(|it| it.variants()) | 72 | .flat_map(|it| it.variants()) |
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 85dc4feb0..dfb79a30a 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | expr::{Expr, ExprId, Pat, PatId}, | 17 | expr::{Expr, ExprId, Pat, PatId}, |
18 | nameres::CrateDefMap, | 18 | nameres::CrateDefMap, |
19 | path::Path, | 19 | path::Path, |
20 | AstItemDef, DefWithBodyId, ModuleId, | 20 | AstItemDef, DefWithBodyId, HasModule, HasSource, Lookup, ModuleId, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | pub struct Expander { | 23 | pub struct Expander { |
@@ -73,8 +73,8 @@ impl Expander { | |||
73 | std::mem::forget(mark); | 73 | std::mem::forget(mark); |
74 | } | 74 | } |
75 | 75 | ||
76 | fn to_source<T>(&self, ast: T) -> Source<T> { | 76 | fn to_source<T>(&self, value: T) -> Source<T> { |
77 | Source { file_id: self.current_file_id, ast } | 77 | Source { file_id: self.current_file_id, value } |
78 | } | 78 | } |
79 | 79 | ||
80 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { | 80 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { |
@@ -149,17 +149,19 @@ impl Body { | |||
149 | 149 | ||
150 | let (file_id, module, body) = match def { | 150 | let (file_id, module, body) = match def { |
151 | DefWithBodyId::FunctionId(f) => { | 151 | DefWithBodyId::FunctionId(f) => { |
152 | let f = f.lookup(db); | ||
152 | let src = f.source(db); | 153 | let src = f.source(db); |
153 | params = src.ast.param_list(); | 154 | params = src.value.param_list(); |
154 | (src.file_id, f.module(db), src.ast.body().map(ast::Expr::from)) | 155 | (src.file_id, f.module(db), src.value.body().map(ast::Expr::from)) |
155 | } | 156 | } |
156 | DefWithBodyId::ConstId(c) => { | 157 | DefWithBodyId::ConstId(c) => { |
158 | let c = c.lookup(db); | ||
157 | let src = c.source(db); | 159 | let src = c.source(db); |
158 | (src.file_id, c.module(db), src.ast.body()) | 160 | (src.file_id, c.module(db), src.value.body()) |
159 | } | 161 | } |
160 | DefWithBodyId::StaticId(s) => { | 162 | DefWithBodyId::StaticId(s) => { |
161 | let src = s.source(db); | 163 | let src = s.source(db); |
162 | (src.file_id, s.module(db), src.ast.body()) | 164 | (src.file_id, s.module(db), src.value.body()) |
163 | } | 165 | } |
164 | }; | 166 | }; |
165 | let expander = Expander::new(db, file_id, module); | 167 | let expander = Expander::new(db, file_id, module); |
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 10cb87d37..aeb71ff22 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -210,8 +210,9 @@ mod tests { | |||
210 | let scopes = db.expr_scopes(function.into()); | 210 | let scopes = db.expr_scopes(function.into()); |
211 | let (_body, source_map) = db.body_with_source_map(function.into()); | 211 | let (_body, source_map) = db.body_with_source_map(function.into()); |
212 | 212 | ||
213 | let expr_id = | 213 | let expr_id = source_map |
214 | source_map.node_expr(Source { file_id: file_id.into(), ast: &marker.into() }).unwrap(); | 214 | .node_expr(Source { file_id: file_id.into(), value: &marker.into() }) |
215 | .unwrap(); | ||
215 | let scope = scopes.scope_for(expr_id); | 216 | let scope = scopes.scope_for(expr_id); |
216 | 217 | ||
217 | let actual = scopes | 218 | let actual = scopes |
@@ -317,14 +318,14 @@ mod tests { | |||
317 | let expr_scope = { | 318 | let expr_scope = { |
318 | let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); | 319 | let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); |
319 | let expr_id = | 320 | let expr_id = |
320 | source_map.node_expr(Source { file_id: file_id.into(), ast: &expr_ast }).unwrap(); | 321 | source_map.node_expr(Source { file_id: file_id.into(), value: &expr_ast }).unwrap(); |
321 | scopes.scope_for(expr_id).unwrap() | 322 | scopes.scope_for(expr_id).unwrap() |
322 | }; | 323 | }; |
323 | 324 | ||
324 | let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap(); | 325 | let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap(); |
325 | let pat_src = source_map.pat_syntax(resolved.pat()).unwrap(); | 326 | let pat_src = source_map.pat_syntax(resolved.pat()).unwrap(); |
326 | 327 | ||
327 | let local_name = pat_src.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); | 328 | let local_name = pat_src.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); |
328 | assert_eq!(local_name.range(), expected_name.syntax().text_range()); | 329 | assert_eq!(local_name.range(), expected_name.syntax().text_range()); |
329 | } | 330 | } |
330 | 331 | ||
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 348aca07f..844f8bbe8 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -8,30 +8,32 @@ use ra_syntax::ast; | |||
8 | use crate::{ | 8 | use crate::{ |
9 | adt::{EnumData, StructData}, | 9 | adt::{EnumData, StructData}, |
10 | body::{scope::ExprScopes, Body, BodySourceMap}, | 10 | body::{scope::ExprScopes, Body, BodySourceMap}, |
11 | imp::ImplData, | 11 | generics::GenericParams, |
12 | impls::ImplData, | ||
12 | nameres::{ | 13 | nameres::{ |
13 | raw::{ImportSourceMap, RawItems}, | 14 | raw::{ImportSourceMap, RawItems}, |
14 | CrateDefMap, | 15 | CrateDefMap, |
15 | }, | 16 | }, |
16 | DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, | 17 | traits::TraitData, |
18 | DefWithBodyId, EnumId, GenericDefId, ImplId, ItemLoc, StructOrUnionId, TraitId, | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | #[salsa::query_group(InternDatabaseStorage)] | 21 | #[salsa::query_group(InternDatabaseStorage)] |
20 | pub trait InternDatabase: SourceDatabase { | 22 | pub trait InternDatabase: SourceDatabase { |
21 | #[salsa::interned] | 23 | #[salsa::interned] |
22 | fn intern_function(&self, loc: ItemLoc<ast::FnDef>) -> crate::FunctionId; | 24 | fn intern_function(&self, loc: crate::FunctionLoc) -> crate::FunctionId; |
23 | #[salsa::interned] | 25 | #[salsa::interned] |
24 | fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId; | 26 | fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId; |
25 | #[salsa::interned] | 27 | #[salsa::interned] |
26 | fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId; | 28 | fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId; |
27 | #[salsa::interned] | 29 | #[salsa::interned] |
28 | fn intern_const(&self, loc: ItemLoc<ast::ConstDef>) -> crate::ConstId; | 30 | fn intern_const(&self, loc: crate::ConstLoc) -> crate::ConstId; |
29 | #[salsa::interned] | 31 | #[salsa::interned] |
30 | fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId; | 32 | fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId; |
31 | #[salsa::interned] | 33 | #[salsa::interned] |
32 | fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId; | 34 | fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId; |
33 | #[salsa::interned] | 35 | #[salsa::interned] |
34 | fn intern_type_alias(&self, loc: ItemLoc<ast::TypeAliasDef>) -> crate::TypeAliasId; | 36 | fn intern_type_alias(&self, loc: crate::TypeAliasLoc) -> crate::TypeAliasId; |
35 | #[salsa::interned] | 37 | #[salsa::interned] |
36 | fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId; | 38 | fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId; |
37 | } | 39 | } |
@@ -59,6 +61,9 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
59 | #[salsa::invoke(ImplData::impl_data_query)] | 61 | #[salsa::invoke(ImplData::impl_data_query)] |
60 | fn impl_data(&self, e: ImplId) -> Arc<ImplData>; | 62 | fn impl_data(&self, e: ImplId) -> Arc<ImplData>; |
61 | 63 | ||
64 | #[salsa::invoke(TraitData::trait_data_query)] | ||
65 | fn trait_data(&self, e: TraitId) -> Arc<TraitData>; | ||
66 | |||
62 | #[salsa::invoke(Body::body_with_source_map_query)] | 67 | #[salsa::invoke(Body::body_with_source_map_query)] |
63 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); | 68 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); |
64 | 69 | ||
@@ -67,4 +72,7 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
67 | 72 | ||
68 | #[salsa::invoke(ExprScopes::expr_scopes_query)] | 73 | #[salsa::invoke(ExprScopes::expr_scopes_query)] |
69 | fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>; | 74 | fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>; |
75 | |||
76 | #[salsa::invoke(GenericParams::generic_params_query)] | ||
77 | fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; | ||
70 | } | 78 | } |
diff --git a/crates/ra_hir_def/src/diagnostics.rs b/crates/ra_hir_def/src/diagnostics.rs index 9843009a5..eda9b2269 100644 --- a/crates/ra_hir_def/src/diagnostics.rs +++ b/crates/ra_hir_def/src/diagnostics.rs | |||
@@ -20,7 +20,7 @@ impl Diagnostic for UnresolvedModule { | |||
20 | "unresolved module".to_string() | 20 | "unresolved module".to_string() |
21 | } | 21 | } |
22 | fn source(&self) -> Source<SyntaxNodePtr> { | 22 | fn source(&self) -> Source<SyntaxNodePtr> { |
23 | Source { file_id: self.file, ast: self.decl.into() } | 23 | Source { file_id: self.file, value: self.decl.into() } |
24 | } | 24 | } |
25 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 25 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
26 | self | 26 | self |
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs new file mode 100644 index 000000000..9e2e4c3cc --- /dev/null +++ b/crates/ra_hir_def/src/generics.rs | |||
@@ -0,0 +1,185 @@ | |||
1 | //! Many kinds of items or constructs can have generic parameters: functions, | ||
2 | //! structs, impls, traits, etc. This module provides a common HIR for these | ||
3 | //! generic parameters. See also the `Generics` type and the `generics_of` query | ||
4 | //! in rustc. | ||
5 | use std::sync::Arc; | ||
6 | |||
7 | use hir_expand::name::{self, AsName, Name}; | ||
8 | use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; | ||
9 | |||
10 | use crate::{ | ||
11 | db::DefDatabase2, | ||
12 | type_ref::{TypeBound, TypeRef}, | ||
13 | AdtId, AstItemDef, ContainerId, GenericDefId, HasSource, Lookup, | ||
14 | }; | ||
15 | |||
16 | /// Data about a generic parameter (to a function, struct, impl, ...). | ||
17 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
18 | pub struct GenericParam { | ||
19 | // FIXME: give generic params proper IDs | ||
20 | pub idx: u32, | ||
21 | pub name: Name, | ||
22 | pub default: Option<TypeRef>, | ||
23 | } | ||
24 | |||
25 | /// Data about the generic parameters of a function, struct, impl, etc. | ||
26 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
27 | pub struct GenericParams { | ||
28 | pub parent_params: Option<Arc<GenericParams>>, | ||
29 | pub params: Vec<GenericParam>, | ||
30 | pub where_predicates: Vec<WherePredicate>, | ||
31 | } | ||
32 | |||
33 | /// A single predicate from a where clause, i.e. `where Type: Trait`. Combined | ||
34 | /// where clauses like `where T: Foo + Bar` are turned into multiple of these. | ||
35 | /// It might still result in multiple actual predicates though, because of | ||
36 | /// associated type bindings like `Iterator<Item = u32>`. | ||
37 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
38 | pub struct WherePredicate { | ||
39 | pub type_ref: TypeRef, | ||
40 | pub bound: TypeBound, | ||
41 | } | ||
42 | |||
43 | impl GenericParams { | ||
44 | pub(crate) fn generic_params_query( | ||
45 | db: &impl DefDatabase2, | ||
46 | def: GenericDefId, | ||
47 | ) -> Arc<GenericParams> { | ||
48 | let parent_generics = parent_generic_def(db, def).map(|it| db.generic_params(it)); | ||
49 | Arc::new(GenericParams::new(db, def.into(), parent_generics)) | ||
50 | } | ||
51 | |||
52 | fn new( | ||
53 | db: &impl DefDatabase2, | ||
54 | def: GenericDefId, | ||
55 | parent_params: Option<Arc<GenericParams>>, | ||
56 | ) -> GenericParams { | ||
57 | let mut generics = | ||
58 | GenericParams { params: Vec::new(), parent_params, where_predicates: Vec::new() }; | ||
59 | let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; | ||
60 | // FIXME: add `: Sized` bound for everything except for `Self` in traits | ||
61 | match def { | ||
62 | GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), | ||
63 | GenericDefId::AdtId(AdtId::StructId(it)) => { | ||
64 | generics.fill(&it.0.source(db).value, start) | ||
65 | } | ||
66 | GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.0.source(db).value, start), | ||
67 | GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), | ||
68 | GenericDefId::TraitId(it) => { | ||
69 | // traits get the Self type as an implicit first type parameter | ||
70 | generics.params.push(GenericParam { | ||
71 | idx: start, | ||
72 | name: name::SELF_TYPE, | ||
73 | default: None, | ||
74 | }); | ||
75 | generics.fill(&it.source(db).value, start + 1); | ||
76 | // add super traits as bounds on Self | ||
77 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar | ||
78 | let self_param = TypeRef::Path(name::SELF_TYPE.into()); | ||
79 | generics.fill_bounds(&it.source(db).value, self_param); | ||
80 | } | ||
81 | GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start), | ||
82 | // Note that we don't add `Self` here: in `impl`s, `Self` is not a | ||
83 | // type-parameter, but rather is a type-alias for impl's target | ||
84 | // type, so this is handled by the resolver. | ||
85 | GenericDefId::ImplId(it) => generics.fill(&it.source(db).value, start), | ||
86 | GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} | ||
87 | } | ||
88 | |||
89 | generics | ||
90 | } | ||
91 | |||
92 | fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) { | ||
93 | if let Some(params) = node.type_param_list() { | ||
94 | self.fill_params(params, start) | ||
95 | } | ||
96 | if let Some(where_clause) = node.where_clause() { | ||
97 | self.fill_where_predicates(where_clause); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) { | ||
102 | for bound in | ||
103 | node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) | ||
104 | { | ||
105 | self.add_where_predicate_from_bound(bound, type_ref.clone()); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { | ||
110 | for (idx, type_param) in params.type_params().enumerate() { | ||
111 | let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); | ||
112 | // FIXME: Use `Path::from_src` | ||
113 | let default = type_param.default_type().map(TypeRef::from_ast); | ||
114 | let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; | ||
115 | self.params.push(param); | ||
116 | |||
117 | let type_ref = TypeRef::Path(name.into()); | ||
118 | self.fill_bounds(&type_param, type_ref); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) { | ||
123 | for pred in where_clause.predicates() { | ||
124 | let type_ref = match pred.type_ref() { | ||
125 | Some(type_ref) => type_ref, | ||
126 | None => continue, | ||
127 | }; | ||
128 | let type_ref = TypeRef::from_ast(type_ref); | ||
129 | for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { | ||
130 | self.add_where_predicate_from_bound(bound, type_ref.clone()); | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { | ||
136 | if bound.has_question_mark() { | ||
137 | // FIXME: remove this bound | ||
138 | return; | ||
139 | } | ||
140 | let bound = TypeBound::from_ast(bound); | ||
141 | self.where_predicates.push(WherePredicate { type_ref, bound }); | ||
142 | } | ||
143 | |||
144 | pub fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { | ||
145 | self.params.iter().find(|p| &p.name == name) | ||
146 | } | ||
147 | |||
148 | pub fn count_parent_params(&self) -> usize { | ||
149 | self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0) | ||
150 | } | ||
151 | |||
152 | pub fn count_params_including_parent(&self) -> usize { | ||
153 | let parent_count = self.count_parent_params(); | ||
154 | parent_count + self.params.len() | ||
155 | } | ||
156 | |||
157 | fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) { | ||
158 | if let Some(parent) = &self.parent_params { | ||
159 | parent.for_each_param(f); | ||
160 | } | ||
161 | self.params.iter().for_each(f); | ||
162 | } | ||
163 | |||
164 | pub fn params_including_parent(&self) -> Vec<&GenericParam> { | ||
165 | let mut vec = Vec::with_capacity(self.count_params_including_parent()); | ||
166 | self.for_each_param(&mut |p| vec.push(p)); | ||
167 | vec | ||
168 | } | ||
169 | } | ||
170 | |||
171 | fn parent_generic_def(db: &impl DefDatabase2, def: GenericDefId) -> Option<GenericDefId> { | ||
172 | let container = match def { | ||
173 | GenericDefId::FunctionId(it) => it.lookup(db).container, | ||
174 | GenericDefId::TypeAliasId(it) => it.lookup(db).container, | ||
175 | GenericDefId::ConstId(it) => it.lookup(db).container, | ||
176 | GenericDefId::EnumVariantId(it) => return Some(it.parent.into()), | ||
177 | GenericDefId::AdtId(_) | GenericDefId::TraitId(_) | GenericDefId::ImplId(_) => return None, | ||
178 | }; | ||
179 | |||
180 | match container { | ||
181 | ContainerId::ImplId(it) => Some(it.into()), | ||
182 | ContainerId::TraitId(it) => Some(it.into()), | ||
183 | ContainerId::ModuleId(_) => None, | ||
184 | } | ||
185 | } | ||
diff --git a/crates/ra_hir_def/src/imp.rs b/crates/ra_hir_def/src/impls.rs index 717991c40..750a869f2 100644 --- a/crates/ra_hir_def/src/imp.rs +++ b/crates/ra_hir_def/src/impls.rs | |||
@@ -5,11 +5,12 @@ | |||
5 | 5 | ||
6 | use std::sync::Arc; | 6 | use std::sync::Arc; |
7 | 7 | ||
8 | use hir_expand::AstId; | ||
8 | use ra_syntax::ast; | 9 | use ra_syntax::ast; |
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
11 | db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionId, ImplId, | 12 | db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstLoc, ContainerId, |
12 | LocationCtx, TypeAliasId, | 13 | FunctionLoc, ImplId, Intern, TypeAliasLoc, |
13 | }; | 14 | }; |
14 | 15 | ||
15 | #[derive(Debug, Clone, PartialEq, Eq)] | 16 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -25,23 +26,37 @@ impl ImplData { | |||
25 | let src = id.source(db); | 26 | let src = id.source(db); |
26 | let items = db.ast_id_map(src.file_id); | 27 | let items = db.ast_id_map(src.file_id); |
27 | 28 | ||
28 | let target_trait = src.ast.target_trait().map(TypeRef::from_ast); | 29 | let target_trait = src.value.target_trait().map(TypeRef::from_ast); |
29 | let target_type = TypeRef::from_ast_opt(src.ast.target_type()); | 30 | let target_type = TypeRef::from_ast_opt(src.value.target_type()); |
30 | let negative = src.ast.is_negative(); | 31 | let negative = src.value.is_negative(); |
31 | 32 | ||
32 | let items = if let Some(item_list) = src.ast.item_list() { | 33 | let items = if let Some(item_list) = src.value.item_list() { |
33 | let ctx = LocationCtx::new(db, id.module(db), src.file_id); | ||
34 | item_list | 34 | item_list |
35 | .impl_items() | 35 | .impl_items() |
36 | .map(|item_node| match item_node { | 36 | .map(|item_node| match item_node { |
37 | ast::ImplItem::FnDef(it) => { | 37 | ast::ImplItem::FnDef(it) => { |
38 | FunctionId::from_ast_id(ctx, items.ast_id(&it)).into() | 38 | let def = FunctionLoc { |
39 | container: ContainerId::ImplId(id), | ||
40 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | ||
41 | } | ||
42 | .intern(db); | ||
43 | def.into() | ||
39 | } | 44 | } |
40 | ast::ImplItem::ConstDef(it) => { | 45 | ast::ImplItem::ConstDef(it) => { |
41 | ConstId::from_ast_id(ctx, items.ast_id(&it)).into() | 46 | let def = ConstLoc { |
47 | container: ContainerId::ImplId(id), | ||
48 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | ||
49 | } | ||
50 | .intern(db); | ||
51 | def.into() | ||
42 | } | 52 | } |
43 | ast::ImplItem::TypeAliasDef(it) => { | 53 | ast::ImplItem::TypeAliasDef(it) => { |
44 | TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into() | 54 | let def = TypeAliasLoc { |
55 | container: ContainerId::ImplId(id), | ||
56 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | ||
57 | } | ||
58 | .intern(db); | ||
59 | def.into() | ||
45 | } | 60 | } |
46 | }) | 61 | }) |
47 | .collect() | 62 | .collect() |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index a240a10b8..0af41de87 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -13,10 +13,12 @@ pub mod path; | |||
13 | pub mod type_ref; | 13 | pub mod type_ref; |
14 | pub mod builtin_type; | 14 | pub mod builtin_type; |
15 | pub mod adt; | 15 | pub mod adt; |
16 | pub mod imp; | 16 | pub mod impls; |
17 | pub mod diagnostics; | 17 | pub mod diagnostics; |
18 | pub mod expr; | 18 | pub mod expr; |
19 | pub mod body; | 19 | pub mod body; |
20 | pub mod generics; | ||
21 | pub mod traits; | ||
20 | 22 | ||
21 | #[cfg(test)] | 23 | #[cfg(test)] |
22 | mod test_db; | 24 | mod test_db; |
@@ -80,7 +82,7 @@ impl ModuleSource { | |||
80 | 82 | ||
81 | pub fn from_child_node(db: &impl db::DefDatabase2, child: Source<&SyntaxNode>) -> ModuleSource { | 83 | pub fn from_child_node(db: &impl db::DefDatabase2, child: Source<&SyntaxNode>) -> ModuleSource { |
82 | if let Some(m) = | 84 | if let Some(m) = |
83 | child.ast.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) | 85 | child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) |
84 | { | 86 | { |
85 | ModuleSource::Module(m) | 87 | ModuleSource::Module(m) |
86 | } else { | 88 | } else { |
@@ -184,8 +186,8 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | |||
184 | } | 186 | } |
185 | fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> { | 187 | fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> { |
186 | let loc = self.lookup_intern(db); | 188 | let loc = self.lookup_intern(db); |
187 | let ast = loc.ast_id.to_node(db); | 189 | let value = loc.ast_id.to_node(db); |
188 | Source { file_id: loc.ast_id.file_id(), ast } | 190 | Source { file_id: loc.ast_id.file_id(), value } |
189 | } | 191 | } |
190 | fn module(self, db: &impl InternDatabase) -> ModuleId { | 192 | fn module(self, db: &impl InternDatabase) -> ModuleId { |
191 | let loc = self.lookup_intern(db); | 193 | let loc = self.lookup_intern(db); |
@@ -197,12 +199,23 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | |||
197 | pub struct FunctionId(salsa::InternId); | 199 | pub struct FunctionId(salsa::InternId); |
198 | impl_intern_key!(FunctionId); | 200 | impl_intern_key!(FunctionId); |
199 | 201 | ||
200 | impl AstItemDef<ast::FnDef> for FunctionId { | 202 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
201 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::FnDef>) -> Self { | 203 | pub struct FunctionLoc { |
202 | db.intern_function(loc) | 204 | pub container: ContainerId, |
205 | pub ast_id: AstId<ast::FnDef>, | ||
206 | } | ||
207 | |||
208 | impl Intern for FunctionLoc { | ||
209 | type ID = FunctionId; | ||
210 | fn intern(self, db: &impl db::DefDatabase2) -> FunctionId { | ||
211 | db.intern_function(self) | ||
203 | } | 212 | } |
204 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::FnDef> { | 213 | } |
205 | db.lookup_intern_function(self) | 214 | |
215 | impl Lookup for FunctionId { | ||
216 | type Data = FunctionLoc; | ||
217 | fn lookup(&self, db: &impl db::DefDatabase2) -> FunctionLoc { | ||
218 | db.lookup_intern_function(*self) | ||
206 | } | 219 | } |
207 | } | 220 | } |
208 | 221 | ||
@@ -276,12 +289,23 @@ impl_arena_id!(LocalStructFieldId); | |||
276 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 289 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
277 | pub struct ConstId(salsa::InternId); | 290 | pub struct ConstId(salsa::InternId); |
278 | impl_intern_key!(ConstId); | 291 | impl_intern_key!(ConstId); |
279 | impl AstItemDef<ast::ConstDef> for ConstId { | 292 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
280 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self { | 293 | pub struct ConstLoc { |
281 | db.intern_const(loc) | 294 | pub container: ContainerId, |
295 | pub ast_id: AstId<ast::ConstDef>, | ||
296 | } | ||
297 | |||
298 | impl Intern for ConstLoc { | ||
299 | type ID = ConstId; | ||
300 | fn intern(self, db: &impl db::DefDatabase2) -> ConstId { | ||
301 | db.intern_const(self) | ||
282 | } | 302 | } |
283 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ConstDef> { | 303 | } |
284 | db.lookup_intern_const(self) | 304 | |
305 | impl Lookup for ConstId { | ||
306 | type Data = ConstLoc; | ||
307 | fn lookup(&self, db: &impl db::DefDatabase2) -> ConstLoc { | ||
308 | db.lookup_intern_const(*self) | ||
285 | } | 309 | } |
286 | } | 310 | } |
287 | 311 | ||
@@ -312,12 +336,24 @@ impl AstItemDef<ast::TraitDef> for TraitId { | |||
312 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 336 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
313 | pub struct TypeAliasId(salsa::InternId); | 337 | pub struct TypeAliasId(salsa::InternId); |
314 | impl_intern_key!(TypeAliasId); | 338 | impl_intern_key!(TypeAliasId); |
315 | impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { | 339 | |
316 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self { | 340 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
317 | db.intern_type_alias(loc) | 341 | pub struct TypeAliasLoc { |
342 | pub container: ContainerId, | ||
343 | pub ast_id: AstId<ast::TypeAliasDef>, | ||
344 | } | ||
345 | |||
346 | impl Intern for TypeAliasLoc { | ||
347 | type ID = TypeAliasId; | ||
348 | fn intern(self, db: &impl db::DefDatabase2) -> TypeAliasId { | ||
349 | db.intern_type_alias(self) | ||
318 | } | 350 | } |
319 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TypeAliasDef> { | 351 | } |
320 | db.lookup_intern_type_alias(self) | 352 | |
353 | impl Lookup for TypeAliasId { | ||
354 | type Data = TypeAliasLoc; | ||
355 | fn lookup(&self, db: &impl db::DefDatabase2) -> TypeAliasLoc { | ||
356 | db.lookup_intern_type_alias(*self) | ||
321 | } | 357 | } |
322 | } | 358 | } |
323 | 359 | ||
@@ -352,6 +388,13 @@ macro_rules! impl_froms { | |||
352 | } | 388 | } |
353 | } | 389 | } |
354 | 390 | ||
391 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
392 | pub enum ContainerId { | ||
393 | ModuleId(ModuleId), | ||
394 | ImplId(ImplId), | ||
395 | TraitId(TraitId), | ||
396 | } | ||
397 | |||
355 | /// A Data Type | 398 | /// A Data Type |
356 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 399 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
357 | pub enum AdtId { | 400 | pub enum AdtId { |
@@ -408,3 +451,102 @@ pub enum AssocItemId { | |||
408 | // require not implementing From, and instead having some checked way of | 451 | // require not implementing From, and instead having some checked way of |
409 | // casting them, and somehow making the constructors private, which would be annoying. | 452 | // casting them, and somehow making the constructors private, which would be annoying. |
410 | impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); | 453 | impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); |
454 | |||
455 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
456 | pub enum GenericDefId { | ||
457 | FunctionId(FunctionId), | ||
458 | AdtId(AdtId), | ||
459 | TraitId(TraitId), | ||
460 | TypeAliasId(TypeAliasId), | ||
461 | ImplId(ImplId), | ||
462 | // enum variants cannot have generics themselves, but their parent enums | ||
463 | // can, and this makes some code easier to write | ||
464 | EnumVariantId(EnumVariantId), | ||
465 | // consts can have type parameters from their parents (i.e. associated consts of traits) | ||
466 | ConstId(ConstId), | ||
467 | } | ||
468 | impl_froms!( | ||
469 | GenericDefId: FunctionId, | ||
470 | AdtId(StructId, EnumId, UnionId), | ||
471 | TraitId, | ||
472 | TypeAliasId, | ||
473 | ImplId, | ||
474 | EnumVariantId, | ||
475 | ConstId | ||
476 | ); | ||
477 | |||
478 | trait Intern { | ||
479 | type ID; | ||
480 | fn intern(self, db: &impl db::DefDatabase2) -> Self::ID; | ||
481 | } | ||
482 | |||
483 | pub trait Lookup { | ||
484 | type Data; | ||
485 | fn lookup(&self, db: &impl db::DefDatabase2) -> Self::Data; | ||
486 | } | ||
487 | |||
488 | pub trait HasModule { | ||
489 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId; | ||
490 | } | ||
491 | |||
492 | impl HasModule for FunctionLoc { | ||
493 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
494 | match self.container { | ||
495 | ContainerId::ModuleId(it) => it, | ||
496 | ContainerId::ImplId(it) => it.module(db), | ||
497 | ContainerId::TraitId(it) => it.module(db), | ||
498 | } | ||
499 | } | ||
500 | } | ||
501 | |||
502 | impl HasModule for TypeAliasLoc { | ||
503 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
504 | match self.container { | ||
505 | ContainerId::ModuleId(it) => it, | ||
506 | ContainerId::ImplId(it) => it.module(db), | ||
507 | ContainerId::TraitId(it) => it.module(db), | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | |||
512 | impl HasModule for ConstLoc { | ||
513 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
514 | match self.container { | ||
515 | ContainerId::ModuleId(it) => it, | ||
516 | ContainerId::ImplId(it) => it.module(db), | ||
517 | ContainerId::TraitId(it) => it.module(db), | ||
518 | } | ||
519 | } | ||
520 | } | ||
521 | |||
522 | pub trait HasSource { | ||
523 | type Value; | ||
524 | fn source(&self, db: &impl db::DefDatabase2) -> Source<Self::Value>; | ||
525 | } | ||
526 | |||
527 | impl HasSource for FunctionLoc { | ||
528 | type Value = ast::FnDef; | ||
529 | |||
530 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::FnDef> { | ||
531 | let node = self.ast_id.to_node(db); | ||
532 | Source::new(self.ast_id.file_id(), node) | ||
533 | } | ||
534 | } | ||
535 | |||
536 | impl HasSource for TypeAliasLoc { | ||
537 | type Value = ast::TypeAliasDef; | ||
538 | |||
539 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::TypeAliasDef> { | ||
540 | let node = self.ast_id.to_node(db); | ||
541 | Source::new(self.ast_id.file_id(), node) | ||
542 | } | ||
543 | } | ||
544 | |||
545 | impl HasSource for ConstLoc { | ||
546 | type Value = ast::ConstDef; | ||
547 | |||
548 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::ConstDef> { | ||
549 | let node = self.ast_id.to_node(db); | ||
550 | Source::new(self.ast_id.file_id(), node) | ||
551 | } | ||
552 | } | ||
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index e5b073a0f..c01e020ef 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -165,6 +165,14 @@ impl ModuleScope { | |||
165 | self.items.iter().chain(BUILTIN_SCOPE.iter()) | 165 | self.items.iter().chain(BUILTIN_SCOPE.iter()) |
166 | } | 166 | } |
167 | 167 | ||
168 | pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ { | ||
169 | self.entries() | ||
170 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) | ||
171 | .flat_map(|per_ns| { | ||
172 | per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) | ||
173 | }) | ||
174 | } | ||
175 | |||
168 | /// Iterate over all module scoped macros | 176 | /// Iterate over all module scoped macros |
169 | pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { | 177 | pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { |
170 | self.items | 178 | self.items |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 8f426b097..aae3dcadf 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -19,9 +19,9 @@ use crate::{ | |||
19 | per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode, | 19 | per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode, |
20 | }, | 20 | }, |
21 | path::{Path, PathKind}, | 21 | path::{Path, PathKind}, |
22 | AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId, ImplId, | 22 | AdtId, AstId, AstItemDef, ConstLoc, ContainerId, CrateModuleId, EnumId, EnumVariantId, |
23 | LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, StructOrUnionId, TraitId, TypeAliasId, | 23 | FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, |
24 | UnionId, | 24 | StructOrUnionId, TraitId, TypeAliasLoc, UnionId, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { | 27 | pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { |
@@ -673,8 +673,13 @@ where | |||
673 | let name = def.name.clone(); | 673 | let name = def.name.clone(); |
674 | let def: PerNs = match def.kind { | 674 | let def: PerNs = match def.kind { |
675 | raw::DefKind::Function(ast_id) => { | 675 | raw::DefKind::Function(ast_id) => { |
676 | let f = FunctionId::from_ast_id(ctx, ast_id); | 676 | let def = FunctionLoc { |
677 | PerNs::values(f.into()) | 677 | container: ContainerId::ModuleId(module), |
678 | ast_id: AstId::new(self.file_id, ast_id), | ||
679 | } | ||
680 | .intern(self.def_collector.db); | ||
681 | |||
682 | PerNs::values(def.into()) | ||
678 | } | 683 | } |
679 | raw::DefKind::Struct(ast_id) => { | 684 | raw::DefKind::Struct(ast_id) => { |
680 | let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); | 685 | let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); |
@@ -687,13 +692,27 @@ where | |||
687 | PerNs::both(u, u) | 692 | PerNs::both(u, u) |
688 | } | 693 | } |
689 | raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), | 694 | raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), |
690 | raw::DefKind::Const(ast_id) => PerNs::values(ConstId::from_ast_id(ctx, ast_id).into()), | 695 | raw::DefKind::Const(ast_id) => { |
696 | let def = ConstLoc { | ||
697 | container: ContainerId::ModuleId(module), | ||
698 | ast_id: AstId::new(self.file_id, ast_id), | ||
699 | } | ||
700 | .intern(self.def_collector.db); | ||
701 | |||
702 | PerNs::values(def.into()) | ||
703 | } | ||
691 | raw::DefKind::Static(ast_id) => { | 704 | raw::DefKind::Static(ast_id) => { |
692 | PerNs::values(StaticId::from_ast_id(ctx, ast_id).into()) | 705 | PerNs::values(StaticId::from_ast_id(ctx, ast_id).into()) |
693 | } | 706 | } |
694 | raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), | 707 | raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), |
695 | raw::DefKind::TypeAlias(ast_id) => { | 708 | raw::DefKind::TypeAlias(ast_id) => { |
696 | PerNs::types(TypeAliasId::from_ast_id(ctx, ast_id).into()) | 709 | let def = TypeAliasLoc { |
710 | container: ContainerId::ModuleId(module), | ||
711 | ast_id: AstId::new(self.file_id, ast_id), | ||
712 | } | ||
713 | .intern(self.def_collector.db); | ||
714 | |||
715 | PerNs::types(def.into()) | ||
697 | } | 716 | } |
698 | }; | 717 | }; |
699 | let resolution = Resolution { def, import: None }; | 718 | let resolution = Resolution { def, import: None }; |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index a0a2c7273..7c68fd638 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -327,7 +327,7 @@ impl RawItemsCollector { | |||
327 | 327 | ||
328 | let mut buf = Vec::new(); | 328 | let mut buf = Vec::new(); |
329 | Path::expand_use_item( | 329 | Path::expand_use_item( |
330 | Source { ast: use_item, file_id: self.file_id }, | 330 | Source { value: use_item, file_id: self.file_id }, |
331 | &self.hygiene, | 331 | &self.hygiene, |
332 | |path, use_tree, is_glob, alias| { | 332 | |path, use_tree, is_glob, alias| { |
333 | let import_data = ImportData { | 333 | let import_data = ImportData { |
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 04039376f..626ebffdc 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs | |||
@@ -71,7 +71,7 @@ impl Path { | |||
71 | hygiene: &Hygiene, | 71 | hygiene: &Hygiene, |
72 | mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>), | 72 | mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>), |
73 | ) { | 73 | ) { |
74 | if let Some(tree) = item_src.ast.use_tree() { | 74 | if let Some(tree) = item_src.value.use_tree() { |
75 | expand_use_tree(None, tree, hygiene, &mut cb); | 75 | expand_use_tree(None, tree, hygiene, &mut cb); |
76 | } | 76 | } |
77 | } | 77 | } |
diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs new file mode 100644 index 000000000..877d73d66 --- /dev/null +++ b/crates/ra_hir_def/src/traits.rs | |||
@@ -0,0 +1,59 @@ | |||
1 | //! HIR for trait definitions. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::{ | ||
6 | name::{AsName, Name}, | ||
7 | AstId, | ||
8 | }; | ||
9 | |||
10 | use ra_syntax::ast::{self, NameOwner}; | ||
11 | |||
12 | use crate::{ | ||
13 | db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId, | ||
14 | TypeAliasLoc, | ||
15 | }; | ||
16 | |||
17 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
18 | pub struct TraitData { | ||
19 | pub name: Option<Name>, | ||
20 | pub items: Vec<AssocItemId>, | ||
21 | pub auto: bool, | ||
22 | } | ||
23 | |||
24 | impl TraitData { | ||
25 | pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> { | ||
26 | let src = tr.source(db); | ||
27 | let name = src.value.name().map(|n| n.as_name()); | ||
28 | let auto = src.value.is_auto(); | ||
29 | let ast_id_map = db.ast_id_map(src.file_id); | ||
30 | let items = if let Some(item_list) = src.value.item_list() { | ||
31 | item_list | ||
32 | .impl_items() | ||
33 | .map(|item_node| match item_node { | ||
34 | ast::ImplItem::FnDef(it) => FunctionLoc { | ||
35 | container: ContainerId::TraitId(tr), | ||
36 | ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), | ||
37 | } | ||
38 | .intern(db) | ||
39 | .into(), | ||
40 | ast::ImplItem::ConstDef(it) => ConstLoc { | ||
41 | container: ContainerId::TraitId(tr), | ||
42 | ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), | ||
43 | } | ||
44 | .intern(db) | ||
45 | .into(), | ||
46 | ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc { | ||
47 | container: ContainerId::TraitId(tr), | ||
48 | ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), | ||
49 | } | ||
50 | .intern(db) | ||
51 | .into(), | ||
52 | }) | ||
53 | .collect() | ||
54 | } else { | ||
55 | Vec::new() | ||
56 | }; | ||
57 | Arc::new(TraitData { name, items, auto }) | ||
58 | } | ||
59 | } | ||