aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-12-07 19:26:33 +0000
committerGitHub <[email protected]>2019-12-07 19:26:33 +0000
commit971df306ada43f6150e12a143873f680e104a866 (patch)
tree913c24e889f3db8044b4b9f11bc3969e7eb02e34 /crates/ra_hir_def
parenta3eb8787452a04400784ba8fed38303232595695 (diff)
parent88c5b1282a5770097c6c768b24bedfc3a6944e08 (diff)
Merge #2494
2494: Get the right analyzer for impls r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/generics.rs128
-rw-r--r--crates/ra_hir_def/src/keys.rs3
-rw-r--r--crates/ra_hir_def/src/lib.rs22
-rw-r--r--crates/ra_hir_def/src/resolver.rs18
4 files changed, 128 insertions, 43 deletions
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 94ce83564..976cf72d0 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -4,20 +4,29 @@
4//! in rustc. 4//! in rustc.
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use hir_expand::name::{self, AsName, Name}; 7use either::Either;
8use ra_arena::Arena; 8use hir_expand::{
9 name::{self, AsName, Name},
10 InFile,
11};
12use ra_arena::{map::ArenaMap, Arena};
13use ra_db::FileId;
9use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; 14use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
10 15
11use crate::{ 16use crate::{
17 child_by_source::ChildBySource,
12 db::DefDatabase, 18 db::DefDatabase,
19 dyn_map::DynMap,
20 keys,
21 src::HasChildSource,
13 src::HasSource, 22 src::HasSource,
14 type_ref::{TypeBound, TypeRef}, 23 type_ref::{TypeBound, TypeRef},
15 AdtId, AstItemDef, GenericDefId, LocalGenericParamId, Lookup, 24 AdtId, AstItemDef, GenericDefId, LocalTypeParamId, Lookup, TypeParamId,
16}; 25};
17 26
18/// Data about a generic parameter (to a function, struct, impl, ...). 27/// Data about a generic parameter (to a function, struct, impl, ...).
19#[derive(Clone, PartialEq, Eq, Debug)] 28#[derive(Clone, PartialEq, Eq, Debug)]
20pub struct GenericParamData { 29pub struct TypeParamData {
21 pub name: Name, 30 pub name: Name,
22 pub default: Option<TypeRef>, 31 pub default: Option<TypeRef>,
23} 32}
@@ -25,7 +34,8 @@ pub struct GenericParamData {
25/// Data about the generic parameters of a function, struct, impl, etc. 34/// Data about the generic parameters of a function, struct, impl, etc.
26#[derive(Clone, PartialEq, Eq, Debug)] 35#[derive(Clone, PartialEq, Eq, Debug)]
27pub struct GenericParams { 36pub struct GenericParams {
28 pub params: Arena<LocalGenericParamId, GenericParamData>, 37 pub types: Arena<LocalTypeParamId, TypeParamData>,
38 // lifetimes: Arena<LocalLifetimeParamId, LifetimeParamData>,
29 pub where_predicates: Vec<WherePredicate>, 39 pub where_predicates: Vec<WherePredicate>,
30} 40}
31 41
@@ -39,52 +49,87 @@ pub struct WherePredicate {
39 pub bound: TypeBound, 49 pub bound: TypeBound,
40} 50}
41 51
52type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>;
53
42impl GenericParams { 54impl GenericParams {
43 pub(crate) fn generic_params_query( 55 pub(crate) fn generic_params_query(
44 db: &impl DefDatabase, 56 db: &impl DefDatabase,
45 def: GenericDefId, 57 def: GenericDefId,
46 ) -> Arc<GenericParams> { 58 ) -> Arc<GenericParams> {
47 Arc::new(GenericParams::new(db, def.into())) 59 let (params, _source_map) = GenericParams::new(db, def.into());
60 Arc::new(params)
48 } 61 }
49 62
50 fn new(db: &impl DefDatabase, def: GenericDefId) -> GenericParams { 63 fn new(db: &impl DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) {
51 let mut generics = GenericParams { params: Arena::default(), where_predicates: Vec::new() }; 64 let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() };
65 let mut sm = ArenaMap::default();
52 // FIXME: add `: Sized` bound for everything except for `Self` in traits 66 // FIXME: add `: Sized` bound for everything except for `Self` in traits
53 match def { 67 let file_id = match def {
54 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value), 68 GenericDefId::FunctionId(it) => {
55 GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value), 69 let src = it.lookup(db).source(db);
56 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value), 70 generics.fill(&mut sm, &src.value);
57 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value), 71 src.file_id
72 }
73 GenericDefId::AdtId(AdtId::StructId(it)) => {
74 let src = it.source(db);
75 generics.fill(&mut sm, &src.value);
76 src.file_id
77 }
78 GenericDefId::AdtId(AdtId::UnionId(it)) => {
79 let src = it.source(db);
80 generics.fill(&mut sm, &src.value);
81 src.file_id
82 }
83 GenericDefId::AdtId(AdtId::EnumId(it)) => {
84 let src = it.source(db);
85 generics.fill(&mut sm, &src.value);
86 src.file_id
87 }
58 GenericDefId::TraitId(it) => { 88 GenericDefId::TraitId(it) => {
89 let src = it.source(db);
90
59 // traits get the Self type as an implicit first type parameter 91 // traits get the Self type as an implicit first type parameter
60 generics.params.alloc(GenericParamData { name: name::SELF_TYPE, default: None }); 92 let self_param_id =
61 generics.fill(&it.source(db).value); 93 generics.types.alloc(TypeParamData { name: name::SELF_TYPE, default: None });
94 sm.insert(self_param_id, Either::Left(src.value.clone()));
62 // add super traits as bounds on Self 95 // add super traits as bounds on Self
63 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 96 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
64 let self_param = TypeRef::Path(name::SELF_TYPE.into()); 97 let self_param = TypeRef::Path(name::SELF_TYPE.into());
65 generics.fill_bounds(&it.source(db).value, self_param); 98 generics.fill_bounds(&src.value, self_param);
99
100 generics.fill(&mut sm, &src.value);
101 src.file_id
102 }
103 GenericDefId::TypeAliasId(it) => {
104 let src = it.lookup(db).source(db);
105 generics.fill(&mut sm, &src.value);
106 src.file_id
66 } 107 }
67 GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value),
68 // Note that we don't add `Self` here: in `impl`s, `Self` is not a 108 // Note that we don't add `Self` here: in `impl`s, `Self` is not a
69 // type-parameter, but rather is a type-alias for impl's target 109 // type-parameter, but rather is a type-alias for impl's target
70 // type, so this is handled by the resolver. 110 // type, so this is handled by the resolver.
71 GenericDefId::ImplId(it) => generics.fill(&it.source(db).value), 111 GenericDefId::ImplId(it) => {
72 GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} 112 let src = it.source(db);
73 } 113 generics.fill(&mut sm, &src.value);
114 src.file_id
115 }
116 // We won't be using this ID anyway
117 GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => FileId(!0).into(),
118 };
74 119
75 generics 120 (generics, InFile::new(file_id, sm))
76 } 121 }
77 122
78 fn fill(&mut self, node: &impl TypeParamsOwner) { 123 fn fill(&mut self, sm: &mut SourceMap, node: &dyn TypeParamsOwner) {
79 if let Some(params) = node.type_param_list() { 124 if let Some(params) = node.type_param_list() {
80 self.fill_params(params) 125 self.fill_params(sm, params)
81 } 126 }
82 if let Some(where_clause) = node.where_clause() { 127 if let Some(where_clause) = node.where_clause() {
83 self.fill_where_predicates(where_clause); 128 self.fill_where_predicates(where_clause);
84 } 129 }
85 } 130 }
86 131
87 fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) { 132 fn fill_bounds(&mut self, node: &dyn ast::TypeBoundsOwner, type_ref: TypeRef) {
88 for bound in 133 for bound in
89 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) 134 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
90 { 135 {
@@ -92,13 +137,14 @@ impl GenericParams {
92 } 137 }
93 } 138 }
94 139
95 fn fill_params(&mut self, params: ast::TypeParamList) { 140 fn fill_params(&mut self, sm: &mut SourceMap, params: ast::TypeParamList) {
96 for type_param in params.type_params() { 141 for type_param in params.type_params() {
97 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); 142 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
98 // FIXME: Use `Path::from_src` 143 // FIXME: Use `Path::from_src`
99 let default = type_param.default_type().map(TypeRef::from_ast); 144 let default = type_param.default_type().map(TypeRef::from_ast);
100 let param = GenericParamData { name: name.clone(), default }; 145 let param = TypeParamData { name: name.clone(), default };
101 self.params.alloc(param); 146 let param_id = self.types.alloc(param);
147 sm.insert(param_id, Either::Right(type_param.clone()));
102 148
103 let type_ref = TypeRef::Path(name.into()); 149 let type_ref = TypeRef::Path(name.into());
104 self.fill_bounds(&type_param, type_ref); 150 self.fill_bounds(&type_param, type_ref);
@@ -127,7 +173,31 @@ impl GenericParams {
127 self.where_predicates.push(WherePredicate { type_ref, bound }); 173 self.where_predicates.push(WherePredicate { type_ref, bound });
128 } 174 }
129 175
130 pub fn find_by_name(&self, name: &Name) -> Option<LocalGenericParamId> { 176 pub fn find_by_name(&self, name: &Name) -> Option<LocalTypeParamId> {
131 self.params.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None }) 177 self.types.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None })
178 }
179}
180
181impl HasChildSource for GenericDefId {
182 type ChildId = LocalTypeParamId;
183 type Value = Either<ast::TraitDef, ast::TypeParam>;
184 fn child_source(&self, db: &impl DefDatabase) -> InFile<SourceMap> {
185 let (_, sm) = GenericParams::new(db, *self);
186 sm
187 }
188}
189
190impl ChildBySource for GenericDefId {
191 fn child_by_source(&self, db: &impl DefDatabase) -> DynMap {
192 let mut res = DynMap::default();
193 let arena_map = self.child_source(db);
194 let arena_map = arena_map.as_ref();
195 for (local_id, src) in arena_map.value.iter() {
196 let id = TypeParamId { parent: *self, local_id };
197 if let Either::Right(type_param) = src {
198 res[keys::TYPE_PARAM].insert(arena_map.with_value(type_param.clone()), id)
199 }
200 }
201 res
132 } 202 }
133} 203}
diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs
index 447b7e3ba..be702a4f8 100644
--- a/crates/ra_hir_def/src/keys.rs
+++ b/crates/ra_hir_def/src/keys.rs
@@ -8,7 +8,7 @@ use rustc_hash::FxHashMap;
8 8
9use crate::{ 9use crate::{
10 dyn_map::{DynMap, Policy}, 10 dyn_map::{DynMap, Policy},
11 ConstId, EnumVariantId, FunctionId, StaticId, StructFieldId, TypeAliasId, 11 ConstId, EnumVariantId, FunctionId, StaticId, StructFieldId, TypeAliasId, TypeParamId,
12}; 12};
13 13
14type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; 14type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>;
@@ -20,6 +20,7 @@ pub const ENUM_VARIANT: Key<ast::EnumVariant, EnumVariantId> = Key::new();
20pub const TYPE_ALIAS: Key<ast::TypeAliasDef, TypeAliasId> = Key::new(); 20pub const TYPE_ALIAS: Key<ast::TypeAliasDef, TypeAliasId> = Key::new();
21pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new(); 21pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new();
22pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new(); 22pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new();
23pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new();
23 24
24/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are 25/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
25/// equal if they point to exactly the same object. 26/// equal if they point to exactly the same object.
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index b8dfc0ab1..569da4f28 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -318,14 +318,14 @@ macro_rules! impl_froms {
318} 318}
319 319
320#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 320#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
321pub struct GenericParamId { 321pub struct TypeParamId {
322 pub parent: GenericDefId, 322 pub parent: GenericDefId,
323 pub local_id: LocalGenericParamId, 323 pub local_id: LocalTypeParamId,
324} 324}
325 325
326#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 326#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
327pub struct LocalGenericParamId(RawId); 327pub struct LocalTypeParamId(RawId);
328impl_arena_id!(LocalGenericParamId); 328impl_arena_id!(LocalTypeParamId);
329 329
330#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 330#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
331pub enum ContainerId { 331pub enum ContainerId {
@@ -525,6 +525,20 @@ impl HasModule for DefWithBodyId {
525 } 525 }
526} 526}
527 527
528impl HasModule for GenericDefId {
529 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
530 match self {
531 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
532 GenericDefId::AdtId(it) => it.module(db),
533 GenericDefId::TraitId(it) => it.module(db),
534 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
535 GenericDefId::ImplId(it) => it.module(db),
536 GenericDefId::EnumVariantId(it) => it.parent.module(db),
537 GenericDefId::ConstId(it) => it.lookup(db).module(db),
538 }
539 }
540}
541
528impl HasModule for StaticLoc { 542impl HasModule for StaticLoc {
529 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { 543 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId {
530 self.container 544 self.container
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index e00bd03d5..4c859e497 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -18,8 +18,8 @@ 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, GenericParamId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, 21 GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId,
22 StaticId, StructId, TraitId, TypeAliasId, 22 StructId, TraitId, TypeAliasId, TypeParamId,
23}; 23};
24 24
25#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -59,7 +59,7 @@ enum Scope {
59#[derive(Debug, Clone, PartialEq, Eq, Hash)] 59#[derive(Debug, Clone, PartialEq, Eq, Hash)]
60pub enum TypeNs { 60pub enum TypeNs {
61 SelfType(ImplId), 61 SelfType(ImplId),
62 GenericParam(GenericParamId), 62 GenericParam(TypeParamId),
63 AdtId(AdtId), 63 AdtId(AdtId),
64 AdtSelfType(AdtId), 64 AdtSelfType(AdtId),
65 // 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
@@ -157,7 +157,7 @@ impl Resolver {
157 if let Some(local_id) = params.find_by_name(first_name) { 157 if let Some(local_id) = params.find_by_name(first_name) {
158 let idx = if path.segments.len() == 1 { None } else { Some(1) }; 158 let idx = if path.segments.len() == 1 { None } else { Some(1) };
159 return Some(( 159 return Some((
160 TypeNs::GenericParam(GenericParamId { local_id, parent: *def }), 160 TypeNs::GenericParam(TypeParamId { local_id, parent: *def }),
161 idx, 161 idx,
162 )); 162 ));
163 } 163 }
@@ -252,7 +252,7 @@ impl Resolver {
252 252
253 Scope::GenericParams { params, def } if n_segments > 1 => { 253 Scope::GenericParams { params, def } if n_segments > 1 => {
254 if let Some(local_id) = params.find_by_name(first_name) { 254 if let Some(local_id) = params.find_by_name(first_name) {
255 let ty = TypeNs::GenericParam(GenericParamId { local_id, parent: *def }); 255 let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def });
256 return Some(ResolveValueResult::Partial(ty, 1)); 256 return Some(ResolveValueResult::Partial(ty, 1));
257 } 257 }
258 } 258 }
@@ -399,7 +399,7 @@ pub enum ScopeDef {
399 PerNs(PerNs), 399 PerNs(PerNs),
400 ImplSelfType(ImplId), 400 ImplSelfType(ImplId),
401 AdtSelfType(AdtId), 401 AdtSelfType(AdtId),
402 GenericParam(GenericParamId), 402 GenericParam(TypeParamId),
403 Local(PatId), 403 Local(PatId),
404} 404}
405 405
@@ -431,10 +431,10 @@ impl Scope {
431 } 431 }
432 } 432 }
433 Scope::GenericParams { params, def } => { 433 Scope::GenericParams { params, def } => {
434 for (local_id, param) in params.params.iter() { 434 for (local_id, param) in params.types.iter() {
435 f( 435 f(
436 param.name.clone(), 436 param.name.clone(),
437 ScopeDef::GenericParam(GenericParamId { local_id, parent: *def }), 437 ScopeDef::GenericParam(TypeParamId { local_id, parent: *def }),
438 ) 438 )
439 } 439 }
440 } 440 }
@@ -481,7 +481,7 @@ impl Resolver {
481 481
482 fn push_generic_params_scope(self, db: &impl DefDatabase, def: GenericDefId) -> Resolver { 482 fn push_generic_params_scope(self, db: &impl DefDatabase, def: GenericDefId) -> Resolver {
483 let params = db.generic_params(def); 483 let params = db.generic_params(def);
484 if params.params.is_empty() { 484 if params.types.is_empty() {
485 self 485 self
486 } else { 486 } else {
487 self.push_scope(Scope::GenericParams { def, params }) 487 self.push_scope(Scope::GenericParams { def, params })