aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs464
1 files changed, 220 insertions, 244 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 92860fb59..534f1f8e9 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1,39 +1,33 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3pub(crate) mod src; 3pub(crate) mod src;
4pub(crate) mod docs;
5pub(crate) mod attrs;
6 4
7use std::sync::Arc; 5use std::sync::Arc;
8 6
9use hir_def::{ 7use hir_def::{
10 adt::VariantData, 8 adt::VariantData,
11 body::scope::ExprScopes,
12 builtin_type::BuiltinType, 9 builtin_type::BuiltinType,
13 nameres::per_ns::PerNs, 10 docs::Documentation,
11 per_ns::PerNs,
14 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
15 traits::TraitData, 13 type_ref::TypeRef,
16 type_ref::{Mutability, TypeRef}, 14 AstItemDef, ConstId, ContainerId, EnumId, FunctionId, GenericDefId, HasModule, ImplId,
17 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, 15 LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId,
18 ModuleId, UnionId, 16 StaticId, StructId, TraitId, TypeAliasId, UnionId,
19}; 17};
20use hir_expand::{ 18use hir_expand::{
21 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
22 name::{self, AsName}, 20 name::{self, AsName},
21 AstId, MacroDefId,
23}; 22};
24use ra_db::{CrateId, Edition}; 23use ra_db::{CrateId, Edition, FileId, FilePosition};
25use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 24use ra_syntax::{ast, AstNode, SyntaxNode};
26 25
27use crate::{ 26use crate::{
28 db::{AstDatabase, DefDatabase, HirDatabase}, 27 db::{DefDatabase, HirDatabase},
29 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 28 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
30 generics::{GenericDef, HasGenericParams},
31 ids::{
32 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId,
33 TypeAliasId,
34 },
35 ty::{InferenceResult, Namespace, TraitRef}, 29 ty::{InferenceResult, Namespace, TraitRef},
36 Either, HasSource, ImportId, Name, Source, Ty, 30 Either, Name, Source, Ty,
37}; 31};
38 32
39/// hir::Crate describes a single crate. It's the main interface with which 33/// hir::Crate describes a single crate. It's the main interface with which
@@ -67,7 +61,7 @@ impl Crate {
67 } 61 }
68 62
69 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { 63 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> {
70 let module_id = db.crate_def_map(self.crate_id).root(); 64 let module_id = db.crate_def_map(self.crate_id).root;
71 Some(Module::new(self, module_id)) 65 Some(Module::new(self, module_id))
72 } 66 }
73 67
@@ -81,6 +75,64 @@ impl Crate {
81 } 75 }
82} 76}
83 77
78pub enum ModuleSource {
79 SourceFile(ast::SourceFile),
80 Module(ast::Module),
81}
82
83impl ModuleSource {
84 pub fn new(
85 db: &impl DefDatabase,
86 file_id: Option<FileId>,
87 decl_id: Option<AstId<ast::Module>>,
88 ) -> ModuleSource {
89 match (file_id, decl_id) {
90 (Some(file_id), _) => {
91 let source_file = db.parse(file_id).tree();
92 ModuleSource::SourceFile(source_file)
93 }
94 (None, Some(item_id)) => {
95 let module = item_id.to_node(db);
96 assert!(module.item_list().is_some(), "expected inline module");
97 ModuleSource::Module(module)
98 }
99 (None, None) => panic!(),
100 }
101 }
102
103 // FIXME: this methods do not belong here
104 pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource {
105 let parse = db.parse(position.file_id);
106 match &ra_syntax::algo::find_node_at_offset::<ast::Module>(
107 parse.tree().syntax(),
108 position.offset,
109 ) {
110 Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
111 _ => {
112 let source_file = parse.tree();
113 ModuleSource::SourceFile(source_file)
114 }
115 }
116 }
117
118 pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource {
119 if let Some(m) =
120 child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
121 {
122 ModuleSource::Module(m)
123 } else {
124 let file_id = child.file_id.original_file(db);
125 let source_file = db.parse(file_id).tree();
126 ModuleSource::SourceFile(source_file)
127 }
128 }
129
130 pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource {
131 let source_file = db.parse(file_id).tree();
132 ModuleSource::SourceFile(source_file)
133 }
134}
135
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 136#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85pub struct Module { 137pub struct Module {
86 pub(crate) id: ModuleId, 138 pub(crate) id: ModuleId,
@@ -112,10 +164,10 @@ impl_froms!(
112 BuiltinType 164 BuiltinType
113); 165);
114 166
115pub use hir_def::ModuleSource; 167pub use hir_def::attr::Attrs;
116 168
117impl Module { 169impl Module {
118 pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module { 170 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
119 Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } 171 Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } }
120 } 172 }
121 173
@@ -132,17 +184,6 @@ impl Module {
132 }) 184 })
133 } 185 }
134 186
135 /// Returns the syntax of the last path segment corresponding to this import
136 pub fn import_source(
137 self,
138 db: &impl HirDatabase,
139 import: ImportId,
140 ) -> Either<ast::UseTree, ast::ExternCrateItem> {
141 let src = self.definition_source(db);
142 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
143 source_map.get(&src.value, import)
144 }
145
146 /// Returns the crate this module is part of. 187 /// Returns the crate this module is part of.
147 pub fn krate(self) -> Crate { 188 pub fn krate(self) -> Crate {
148 Crate { crate_id: self.id.krate } 189 Crate { crate_id: self.id.krate }
@@ -153,7 +194,7 @@ impl Module {
153 /// in the module tree of any target in `Cargo.toml`. 194 /// in the module tree of any target in `Cargo.toml`.
154 pub fn crate_root(self, db: &impl DefDatabase) -> Module { 195 pub fn crate_root(self, db: &impl DefDatabase) -> Module {
155 let def_map = db.crate_def_map(self.id.krate); 196 let def_map = db.crate_def_map(self.id.krate);
156 self.with_module_id(def_map.root()) 197 self.with_module_id(def_map.root)
157 } 198 }
158 199
159 /// Finds a child module with the specified name. 200 /// Finds a child module with the specified name.
@@ -192,11 +233,13 @@ impl Module {
192 } 233 }
193 234
194 /// Returns a `ModuleScope`: a set of items, visible in this module. 235 /// Returns a `ModuleScope`: a set of items, visible in this module.
195 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<ImportId>)> { 236 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> {
196 db.crate_def_map(self.id.krate)[self.id.module_id] 237 db.crate_def_map(self.id.krate)[self.id.module_id]
197 .scope 238 .scope
198 .entries() 239 .entries()
199 .map(|(name, res)| (name.clone(), res.def.into(), res.import)) 240 .map(|(name, res)| {
241 (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id }))
242 })
200 .collect() 243 .collect()
201 } 244 }
202 245
@@ -234,11 +277,16 @@ impl Module {
234 def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() 277 def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect()
235 } 278 }
236 279
237 fn with_module_id(self, module_id: CrateModuleId) -> Module { 280 fn with_module_id(self, module_id: LocalModuleId) -> Module {
238 Module::new(self.krate(), module_id) 281 Module::new(self.krate(), module_id)
239 } 282 }
240} 283}
241 284
285pub struct Import {
286 pub(crate) parent: Module,
287 pub(crate) id: LocalImportId,
288}
289
242#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 290#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
243pub struct StructField { 291pub struct StructField {
244 pub(crate) parent: VariantDef, 292 pub(crate) parent: VariantDef,
@@ -253,11 +301,11 @@ pub enum FieldSource {
253 301
254impl StructField { 302impl StructField {
255 pub fn name(&self, db: &impl HirDatabase) -> Name { 303 pub fn name(&self, db: &impl HirDatabase) -> Name {
256 self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() 304 self.parent.variant_data(db).fields()[self.id].name.clone()
257 } 305 }
258 306
259 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 307 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
260 db.type_for_field(*self) 308 db.field_types(self.parent.into())[self.id].clone()
261 } 309 }
262 310
263 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { 311 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef {
@@ -287,8 +335,7 @@ impl Struct {
287 db.struct_data(self.id.into()) 335 db.struct_data(self.id.into())
288 .variant_data 336 .variant_data
289 .fields() 337 .fields()
290 .into_iter() 338 .iter()
291 .flat_map(|it| it.iter())
292 .map(|(id, _)| StructField { parent: self.into(), id }) 339 .map(|(id, _)| StructField { parent: self.into(), id })
293 .collect() 340 .collect()
294 } 341 }
@@ -297,8 +344,7 @@ impl Struct {
297 db.struct_data(self.id.into()) 344 db.struct_data(self.id.into())
298 .variant_data 345 .variant_data
299 .fields() 346 .fields()
300 .into_iter() 347 .iter()
301 .flat_map(|it| it.iter())
302 .find(|(_id, data)| data.name == *name) 348 .find(|(_id, data)| data.name == *name)
303 .map(|(id, _)| StructField { parent: self.into(), id }) 349 .map(|(id, _)| StructField { parent: self.into(), id })
304 } 350 }
@@ -395,8 +441,7 @@ impl EnumVariant {
395 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 441 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
396 self.variant_data(db) 442 self.variant_data(db)
397 .fields() 443 .fields()
398 .into_iter() 444 .iter()
399 .flat_map(|it| it.iter())
400 .map(|(id, _)| StructField { parent: self.into(), id }) 445 .map(|(id, _)| StructField { parent: self.into(), id })
401 .collect() 446 .collect()
402 } 447 }
@@ -404,8 +449,7 @@ impl EnumVariant {
404 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 449 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
405 self.variant_data(db) 450 self.variant_data(db)
406 .fields() 451 .fields()
407 .into_iter() 452 .iter()
408 .flat_map(|it| it.iter())
409 .find(|(_id, data)| data.name == *name) 453 .find(|(_id, data)| data.name == *name)
410 .map(|(id, _)| StructField { parent: self.into(), id }) 454 .map(|(id, _)| StructField { parent: self.into(), id })
411 } 455 }
@@ -461,7 +505,7 @@ impl VariantDef {
461 } 505 }
462 } 506 }
463 507
464 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 508 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
465 match self { 509 match self {
466 VariantDef::Struct(it) => it.field(db, name), 510 VariantDef::Struct(it) => it.field(db, name),
467 VariantDef::EnumVariant(it) => it.field(db, name), 511 VariantDef::EnumVariant(it) => it.field(db, name),
@@ -511,128 +555,11 @@ impl DefWithBody {
511 } 555 }
512} 556}
513 557
514pub trait HasBody: Copy {
515 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>;
516 fn body(self, db: &impl HirDatabase) -> Arc<Body>;
517 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>;
518 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes>;
519}
520
521impl<T> HasBody for T
522where
523 T: Into<DefWithBody> + Copy + HasSource,
524{
525 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
526 db.infer(self.into())
527 }
528
529 fn body(self, db: &impl HirDatabase) -> Arc<Body> {
530 self.into().body(db)
531 }
532
533 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
534 self.into().body_source_map(db)
535 }
536
537 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
538 self.into().expr_scopes(db)
539 }
540}
541
542impl HasBody for DefWithBody {
543 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
544 db.infer(self)
545 }
546
547 fn body(self, db: &impl HirDatabase) -> Arc<Body> {
548 db.body(self.into())
549 }
550
551 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
552 db.body_with_source_map(self.into()).1
553 }
554
555 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
556 db.expr_scopes(self.into())
557 }
558}
559
560#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 558#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
561pub struct Function { 559pub struct Function {
562 pub(crate) id: FunctionId, 560 pub(crate) id: FunctionId,
563} 561}
564 562
565#[derive(Debug, Clone, PartialEq, Eq)]
566pub struct FnData {
567 pub(crate) name: Name,
568 pub(crate) params: Vec<TypeRef>,
569 pub(crate) ret_type: TypeRef,
570 /// True if the first param is `self`. This is relevant to decide whether this
571 /// can be called as a method.
572 pub(crate) has_self_param: bool,
573}
574
575impl FnData {
576 pub(crate) fn fn_data_query(
577 db: &(impl DefDatabase + AstDatabase),
578 func: Function,
579 ) -> Arc<FnData> {
580 let src = func.source(db);
581 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
582 let mut params = Vec::new();
583 let mut has_self_param = false;
584 if let Some(param_list) = src.value.param_list() {
585 if let Some(self_param) = param_list.self_param() {
586 let self_type = if let Some(type_ref) = self_param.ascribed_type() {
587 TypeRef::from_ast(type_ref)
588 } else {
589 let self_type = TypeRef::Path(name::SELF_TYPE.into());
590 match self_param.kind() {
591 ast::SelfParamKind::Owned => self_type,
592 ast::SelfParamKind::Ref => {
593 TypeRef::Reference(Box::new(self_type), Mutability::Shared)
594 }
595 ast::SelfParamKind::MutRef => {
596 TypeRef::Reference(Box::new(self_type), Mutability::Mut)
597 }
598 }
599 };
600 params.push(self_type);
601 has_self_param = true;
602 }
603 for param in param_list.params() {
604 let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
605 params.push(type_ref);
606 }
607 }
608 let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
609 TypeRef::from_ast(type_ref)
610 } else {
611 TypeRef::unit()
612 };
613
614 let sig = FnData { name, params, ret_type, has_self_param };
615 Arc::new(sig)
616 }
617 pub fn name(&self) -> &Name {
618 &self.name
619 }
620
621 pub fn params(&self) -> &[TypeRef] {
622 &self.params
623 }
624
625 pub fn ret_type(&self) -> &TypeRef {
626 &self.ret_type
627 }
628
629 /// True if the first arg is `self`. This is relevant to decide whether this
630 /// can be called as a method.
631 pub fn has_self_param(&self) -> bool {
632 self.has_self_param
633 }
634}
635
636impl Function { 563impl Function {
637 pub fn module(self, db: &impl DefDatabase) -> Module { 564 pub fn module(self, db: &impl DefDatabase) -> Module {
638 self.id.lookup(db).module(db).into() 565 self.id.lookup(db).module(db).into()
@@ -643,10 +570,18 @@ impl Function {
643 } 570 }
644 571
645 pub fn name(self, db: &impl HirDatabase) -> Name { 572 pub fn name(self, db: &impl HirDatabase) -> Name {
646 self.data(db).name.clone() 573 db.function_data(self.id).name.clone()
574 }
575
576 pub fn has_self_param(self, db: &impl HirDatabase) -> bool {
577 db.function_data(self.id).has_self_param
578 }
579
580 pub fn params(self, db: &impl HirDatabase) -> Vec<TypeRef> {
581 db.function_data(self.id).params.clone()
647 } 582 }
648 583
649 pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { 584 pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
650 db.body_with_source_map(self.id.into()).1 585 db.body_with_source_map(self.id.into()).1
651 } 586 }
652 587
@@ -658,10 +593,6 @@ impl Function {
658 db.type_for_def(self.into(), Namespace::Values) 593 db.type_for_def(self.into(), Namespace::Values)
659 } 594 }
660 595
661 pub fn data(self, db: &impl HirDatabase) -> Arc<FnData> {
662 db.fn_data(self)
663 }
664
665 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 596 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
666 db.infer(self.into()) 597 db.infer(self.into())
667 } 598 }
@@ -712,12 +643,8 @@ impl Const {
712 Some(self.module(db).krate()) 643 Some(self.module(db).krate())
713 } 644 }
714 645
715 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> {
716 db.const_data(self)
717 }
718
719 pub fn name(self, db: &impl HirDatabase) -> Option<Name> { 646 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
720 self.data(db).name().cloned() 647 db.const_data(self.id).name.clone()
721 } 648 }
722 649
723 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 650 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
@@ -749,45 +676,6 @@ impl Const {
749 } 676 }
750} 677}
751 678
752#[derive(Debug, Clone, PartialEq, Eq)]
753pub struct ConstData {
754 pub(crate) name: Option<Name>,
755 pub(crate) type_ref: TypeRef,
756}
757
758impl ConstData {
759 pub fn name(&self) -> Option<&Name> {
760 self.name.as_ref()
761 }
762
763 pub fn type_ref(&self) -> &TypeRef {
764 &self.type_ref
765 }
766
767 pub(crate) fn const_data_query(
768 db: &(impl DefDatabase + AstDatabase),
769 konst: Const,
770 ) -> Arc<ConstData> {
771 let node = konst.source(db).value;
772 const_data_for(&node)
773 }
774
775 pub(crate) fn static_data_query(
776 db: &(impl DefDatabase + AstDatabase),
777 konst: Static,
778 ) -> Arc<ConstData> {
779 let node = konst.source(db).value;
780 const_data_for(&node)
781 }
782}
783
784fn const_data_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstData> {
785 let name = node.name().map(|n| n.as_name());
786 let type_ref = TypeRef::from_ast_opt(node.ascribed_type());
787 let sig = ConstData { name, type_ref };
788 Arc::new(sig)
789}
790
791#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 679#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
792pub struct Static { 680pub struct Static {
793 pub(crate) id: StaticId, 681 pub(crate) id: StaticId,
@@ -795,17 +683,13 @@ pub struct Static {
795 683
796impl Static { 684impl Static {
797 pub fn module(self, db: &impl DefDatabase) -> Module { 685 pub fn module(self, db: &impl DefDatabase) -> Module {
798 Module { id: self.id.module(db) } 686 Module { id: self.id.lookup(db).module(db) }
799 } 687 }
800 688
801 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 689 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
802 Some(self.module(db).krate()) 690 Some(self.module(db).krate())
803 } 691 }
804 692
805 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> {
806 db.static_data(self)
807 }
808
809 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 693 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
810 db.infer(self.into()) 694 db.infer(self.into())
811 } 695 }
@@ -822,11 +706,11 @@ impl Trait {
822 } 706 }
823 707
824 pub fn name(self, db: &impl DefDatabase) -> Option<Name> { 708 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
825 self.trait_data(db).name.clone() 709 db.trait_data(self.id).name.clone()
826 } 710 }
827 711
828 pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { 712 pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> {
829 self.trait_data(db).items.iter().map(|it| (*it).into()).collect() 713 db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect()
830 } 714 }
831 715
832 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { 716 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
@@ -835,7 +719,7 @@ impl Trait {
835 // lifetime problems, but since there usually shouldn't be more than a 719 // lifetime problems, but since there usually shouldn't be more than a
836 // few direct traits this should be fine (we could even use some kind of 720 // few direct traits this should be fine (we could even use some kind of
837 // SmallVec if performance is a concern) 721 // SmallVec if performance is a concern)
838 self.generic_params(db) 722 db.generic_params(self.id.into())
839 .where_predicates 723 .where_predicates
840 .iter() 724 .iter()
841 .filter_map(|pred| match &pred.type_ref { 725 .filter_map(|pred| match &pred.type_ref {
@@ -872,7 +756,7 @@ impl Trait {
872 } 756 }
873 757
874 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { 758 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
875 let trait_data = self.trait_data(db); 759 let trait_data = db.trait_data(self.id);
876 let res = 760 let res =
877 trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; 761 trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?;
878 Some(res) 762 Some(res)
@@ -886,16 +770,12 @@ impl Trait {
886 self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) 770 self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name))
887 } 771 }
888 772
889 pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> {
890 db.trait_data(self.id)
891 }
892
893 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { 773 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {
894 TraitRef::for_trait(db, self) 774 TraitRef::for_trait(db, self)
895 } 775 }
896 776
897 pub fn is_auto(self, db: &impl DefDatabase) -> bool { 777 pub fn is_auto(self, db: &impl DefDatabase) -> bool {
898 self.trait_data(db).auto 778 db.trait_data(self.id).auto
899 } 779 }
900} 780}
901 781
@@ -938,7 +818,7 @@ impl TypeAlias {
938 } 818 }
939 819
940 pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { 820 pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> {
941 db.type_alias_data(self).type_ref.clone() 821 db.type_alias_data(self.id).type_ref.clone()
942 } 822 }
943 823
944 pub fn ty(self, db: &impl HirDatabase) -> Ty { 824 pub fn ty(self, db: &impl HirDatabase) -> Ty {
@@ -946,7 +826,7 @@ impl TypeAlias {
946 } 826 }
947 827
948 pub fn name(self, db: &impl DefDatabase) -> Name { 828 pub fn name(self, db: &impl DefDatabase) -> Name {
949 db.type_alias_data(self).name.clone() 829 db.type_alias_data(self.id).name.clone()
950 } 830 }
951} 831}
952 832
@@ -975,16 +855,6 @@ pub enum AssocItem {
975// casting them, and somehow making the constructors private, which would be annoying. 855// casting them, and somehow making the constructors private, which would be annoying.
976impl_froms!(AssocItem: Function, Const, TypeAlias); 856impl_froms!(AssocItem: Function, Const, TypeAlias);
977 857
978impl From<AssocItem> for crate::generics::GenericDef {
979 fn from(item: AssocItem) -> Self {
980 match item {
981 AssocItem::Function(f) => f.into(),
982 AssocItem::Const(c) => c.into(),
983 AssocItem::TypeAlias(t) => t.into(),
984 }
985 }
986}
987
988impl AssocItem { 858impl AssocItem {
989 pub fn module(self, db: &impl DefDatabase) -> Module { 859 pub fn module(self, db: &impl DefDatabase) -> Module {
990 match self { 860 match self {
@@ -1004,6 +874,29 @@ impl AssocItem {
1004 } 874 }
1005} 875}
1006 876
877#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
878pub enum GenericDef {
879 Function(Function),
880 Adt(Adt),
881 Trait(Trait),
882 TypeAlias(TypeAlias),
883 ImplBlock(ImplBlock),
884 // enum variants cannot have generics themselves, but their parent enums
885 // can, and this makes some code easier to write
886 EnumVariant(EnumVariant),
887 // consts can have type parameters from their parents (i.e. associated consts of traits)
888 Const(Const),
889}
890impl_froms!(
891 GenericDef: Function,
892 Adt(Struct, Enum, Union),
893 Trait,
894 TypeAlias,
895 ImplBlock,
896 EnumVariant,
897 Const
898);
899
1007#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 900#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1008pub struct Local { 901pub struct Local {
1009 pub(crate) parent: DefWithBody, 902 pub(crate) parent: DefWithBody,
@@ -1012,7 +905,7 @@ pub struct Local {
1012 905
1013impl Local { 906impl Local {
1014 pub fn name(self, db: &impl HirDatabase) -> Option<Name> { 907 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
1015 let body = self.parent.body(db); 908 let body = db.body(self.parent.into());
1016 match &body[self.pat_id] { 909 match &body[self.pat_id] {
1017 Pat::Bind { name, .. } => Some(name.clone()), 910 Pat::Bind { name, .. } => Some(name.clone()),
1018 _ => None, 911 _ => None,
@@ -1024,7 +917,7 @@ impl Local {
1024 } 917 }
1025 918
1026 pub fn is_mut(self, db: &impl HirDatabase) -> bool { 919 pub fn is_mut(self, db: &impl HirDatabase) -> bool {
1027 let body = self.parent.body(db); 920 let body = db.body(self.parent.into());
1028 match &body[self.pat_id] { 921 match &body[self.pat_id] {
1029 Pat::Bind { mode, .. } => match mode { 922 Pat::Bind { mode, .. } => match mode {
1030 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, 923 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
@@ -1048,7 +941,7 @@ impl Local {
1048 } 941 }
1049 942
1050 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { 943 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> {
1051 let source_map = self.parent.body_source_map(db); 944 let (_body, source_map) = db.body_with_source_map(self.parent.into());
1052 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... 945 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
1053 let root = src.file_syntax(db); 946 let root = src.file_syntax(db);
1054 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) 947 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root)))
@@ -1057,7 +950,7 @@ impl Local {
1057 950
1058#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 951#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1059pub struct GenericParam { 952pub struct GenericParam {
1060 pub(crate) parent: GenericDef, 953 pub(crate) parent: GenericDefId,
1061 pub(crate) idx: u32, 954 pub(crate) idx: u32,
1062} 955}
1063 956
@@ -1066,6 +959,41 @@ pub struct ImplBlock {
1066 pub(crate) id: ImplId, 959 pub(crate) id: ImplId,
1067} 960}
1068 961
962impl ImplBlock {
963 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
964 db.impl_data(self.id).target_trait.clone()
965 }
966
967 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
968 db.impl_data(self.id).target_type.clone()
969 }
970
971 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
972 Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db))
973 }
974
975 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
976 let target_ty = self.target_ty(db);
977 TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty))
978 }
979
980 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
981 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
982 }
983
984 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
985 db.impl_data(self.id).is_negative
986 }
987
988 pub fn module(&self, db: &impl DefDatabase) -> Module {
989 self.id.module(db).into()
990 }
991
992 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
993 Crate { crate_id: self.module(db).id.krate }
994 }
995}
996
1069/// For IDE only 997/// For IDE only
1070pub enum ScopeDef { 998pub enum ScopeDef {
1071 ModuleDef(ModuleDef), 999 ModuleDef(ModuleDef),
@@ -1083,8 +1011,56 @@ impl From<PerNs> for ScopeDef {
1083 .or_else(|| def.take_values()) 1011 .or_else(|| def.take_values())
1084 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) 1012 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
1085 .or_else(|| { 1013 .or_else(|| {
1086 def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) 1014 def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
1087 }) 1015 })
1088 .unwrap_or(ScopeDef::Unknown) 1016 .unwrap_or(ScopeDef::Unknown)
1089 } 1017 }
1090} 1018}
1019
1020#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1021pub enum AttrDef {
1022 Module(Module),
1023 StructField(StructField),
1024 Adt(Adt),
1025 Function(Function),
1026 EnumVariant(EnumVariant),
1027 Static(Static),
1028 Const(Const),
1029 Trait(Trait),
1030 TypeAlias(TypeAlias),
1031 MacroDef(MacroDef),
1032}
1033
1034impl_froms!(
1035 AttrDef: Module,
1036 StructField,
1037 Adt(Struct, Enum, Union),
1038 EnumVariant,
1039 Static,
1040 Const,
1041 Function,
1042 Trait,
1043 TypeAlias,
1044 MacroDef
1045);
1046
1047pub trait HasAttrs {
1048 fn attrs(self, db: &impl DefDatabase) -> Attrs;
1049}
1050
1051impl<T: Into<AttrDef>> HasAttrs for T {
1052 fn attrs(self, db: &impl DefDatabase) -> Attrs {
1053 let def: AttrDef = self.into();
1054 db.attrs(def.into())
1055 }
1056}
1057
1058pub trait Docs {
1059 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>;
1060}
1061impl<T: Into<AttrDef> + Copy> Docs for T {
1062 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
1063 let def: AttrDef = (*self).into();
1064 db.documentation(def.into())
1065 }
1066}