aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/adt.rs54
-rw-r--r--crates/ra_hir/src/code_model.rs278
-rw-r--r--crates/ra_hir/src/code_model/attrs.rs6
-rw-r--r--crates/ra_hir/src/code_model/docs.rs24
-rw-r--r--crates/ra_hir/src/code_model/src.rs34
-rw-r--r--crates/ra_hir/src/db.rs17
-rw-r--r--crates/ra_hir/src/diagnostics.rs10
-rw-r--r--crates/ra_hir/src/expr.rs5
-rw-r--r--crates/ra_hir/src/from_id.rs44
-rw-r--r--crates/ra_hir/src/from_source.rs160
-rw-r--r--crates/ra_hir/src/generics.rs190
-rw-r--r--crates/ra_hir/src/impl_block.rs20
-rw-r--r--crates/ra_hir/src/lang_item.rs4
-rw-r--r--crates/ra_hir/src/lib.rs9
-rw-r--r--crates/ra_hir/src/resolve.rs139
-rw-r--r--crates/ra_hir/src/source_binder.rs60
-rw-r--r--crates/ra_hir/src/traits.rs82
-rw-r--r--crates/ra_hir/src/ty.rs25
-rw-r--r--crates/ra_hir/src/ty/display.rs43
-rw-r--r--crates/ra_hir/src/ty/infer.rs5
-rw-r--r--crates/ra_hir/src/ty/lower.rs9
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs6
-rw-r--r--crates/ra_hir/src/ty/tests.rs39
-rw-r--r--crates/ra_hir/src/type_alias.rs2
24 files changed, 597 insertions, 668 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
deleted file mode 100644
index 945f236c2..000000000
--- a/crates/ra_hir/src/adt.rs
+++ /dev/null
@@ -1,54 +0,0 @@
1//! This module contains the implementation details of the HIR for ADTs, i.e.
2//! structs and enums (and unions).
3
4use std::sync::Arc;
5
6use hir_def::adt::VariantData;
7
8use crate::{
9 db::{DefDatabase, HirDatabase},
10 EnumVariant, Module, Name, Struct, StructField,
11};
12
13impl Struct {
14 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
15 db.struct_data(self.id.into()).variant_data.clone()
16 }
17}
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
20pub enum VariantDef {
21 Struct(Struct),
22 EnumVariant(EnumVariant),
23}
24impl_froms!(VariantDef: Struct, EnumVariant);
25
26impl VariantDef {
27 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
28 match self {
29 VariantDef::Struct(it) => it.fields(db),
30 VariantDef::EnumVariant(it) => it.fields(db),
31 }
32 }
33
34 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
35 match self {
36 VariantDef::Struct(it) => it.field(db, name),
37 VariantDef::EnumVariant(it) => it.field(db, name),
38 }
39 }
40
41 pub fn module(self, db: &impl HirDatabase) -> Module {
42 match self {
43 VariantDef::Struct(it) => it.module(db),
44 VariantDef::EnumVariant(it) => it.module(db),
45 }
46 }
47
48 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
49 match self {
50 VariantDef::Struct(it) => it.variant_data(db),
51 VariantDef::EnumVariant(it) => it.variant_data(db),
52 }
53 }
54}
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 731cc1fff..a132d128b 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -10,8 +10,10 @@ use hir_def::{
10 adt::VariantData, 10 adt::VariantData,
11 body::scope::ExprScopes, 11 body::scope::ExprScopes,
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 traits::TraitData,
13 type_ref::{Mutability, TypeRef}, 14 type_ref::{Mutability, TypeRef},
14 CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, 15 AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId,
16 LocalStructFieldId, Lookup, ModuleId, UnionId,
15}; 17};
16use hir_expand::{ 18use hir_expand::{
17 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -21,7 +23,6 @@ use ra_db::{CrateId, Edition};
21use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 23use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
22 24
23use crate::{ 25use crate::{
24 adt::VariantDef,
25 db::{AstDatabase, DefDatabase, HirDatabase}, 26 db::{AstDatabase, DefDatabase, HirDatabase},
26 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 27 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
27 generics::{GenericDef, HasGenericParams}, 28 generics::{GenericDef, HasGenericParams},
@@ -29,8 +30,7 @@ use crate::{
29 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, 30 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId,
30 TypeAliasId, 31 TypeAliasId,
31 }, 32 },
32 resolve::{Resolver, Scope, TypeNs}, 33 resolve::{HasResolver, TypeNs},
33 traits::TraitData,
34 ty::{InferenceResult, Namespace, TraitRef}, 34 ty::{InferenceResult, Namespace, TraitRef},
35 Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, 35 Either, HasSource, ImportId, Name, ScopeDef, Source, Ty,
36}; 36};
@@ -139,7 +139,7 @@ impl Module {
139 ) -> Either<ast::UseTree, ast::ExternCrateItem> { 139 ) -> Either<ast::UseTree, ast::ExternCrateItem> {
140 let src = self.definition_source(db); 140 let src = self.definition_source(db);
141 let (_, source_map) = db.raw_items_with_source_map(src.file_id); 141 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
142 source_map.get(&src.ast, import) 142 source_map.get(&src.value, import)
143 } 143 }
144 144
145 /// Returns the crate this module is part of. 145 /// Returns the crate this module is part of.
@@ -206,7 +206,7 @@ impl Module {
206 crate::ModuleDef::Function(f) => f.diagnostics(db, sink), 206 crate::ModuleDef::Function(f) => f.diagnostics(db, sink),
207 crate::ModuleDef::Module(m) => { 207 crate::ModuleDef::Module(m) => {
208 // Only add diagnostics from inline modules 208 // Only add diagnostics from inline modules
209 if let ModuleSource::Module(_) = m.definition_source(db).ast { 209 if let ModuleSource::Module(_) = m.definition_source(db).value {
210 m.diagnostics(db, sink) 210 m.diagnostics(db, sink)
211 } 211 }
212 } 212 }
@@ -223,22 +223,9 @@ impl Module {
223 } 223 }
224 } 224 }
225 225
226 pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
227 let def_map = db.crate_def_map(self.id.krate);
228 Resolver::default().push_module_scope(def_map, self.id.module_id)
229 }
230
231 pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { 226 pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> {
232 let def_map = db.crate_def_map(self.id.krate); 227 let def_map = db.crate_def_map(self.id.krate);
233 def_map[self.id.module_id] 228 def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect()
234 .scope
235 .entries()
236 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
237 .flat_map(|per_ns| {
238 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
239 })
240 .map(ModuleDef::from)
241 .collect()
242 } 229 }
243 230
244 pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { 231 pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> {
@@ -323,15 +310,8 @@ impl Struct {
323 db.type_for_def(self.into(), Namespace::Values) 310 db.type_for_def(self.into(), Namespace::Values)
324 } 311 }
325 312
326 // FIXME move to a more general type 313 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
327 /// Builds a resolver for type references inside this struct. 314 db.struct_data(self.id.into()).variant_data.clone()
328 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
329 // take the outer scope...
330 let r = self.module(db).resolver(db);
331 // ...and add generic params, if present
332 let p = self.generic_params(db);
333 let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
334 r
335 } 315 }
336} 316}
337 317
@@ -345,24 +325,13 @@ impl Union {
345 db.struct_data(self.id.into()).name.clone() 325 db.struct_data(self.id.into()).name.clone()
346 } 326 }
347 327
348 pub fn module(self, db: &impl HirDatabase) -> Module { 328 pub fn module(self, db: &impl DefDatabase) -> Module {
349 Module { id: self.id.0.module(db) } 329 Module { id: self.id.0.module(db) }
350 } 330 }
351 331
352 pub fn ty(self, db: &impl HirDatabase) -> Ty { 332 pub fn ty(self, db: &impl HirDatabase) -> Ty {
353 db.type_for_def(self.into(), Namespace::Types) 333 db.type_for_def(self.into(), Namespace::Types)
354 } 334 }
355
356 // FIXME move to a more general type
357 /// Builds a resolver for type references inside this union.
358 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
359 // take the outer scope...
360 let r = self.module(db).resolver(db);
361 // ...and add generic params, if present
362 let p = self.generic_params(db);
363 let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
364 r
365 }
366} 335}
367 336
368#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 337#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -402,17 +371,6 @@ impl Enum {
402 pub fn ty(self, db: &impl HirDatabase) -> Ty { 371 pub fn ty(self, db: &impl HirDatabase) -> Ty {
403 db.type_for_def(self.into(), Namespace::Types) 372 db.type_for_def(self.into(), Namespace::Types)
404 } 373 }
405
406 // FIXME: move to a more general type
407 /// Builds a resolver for type references inside this struct.
408 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
409 // take the outer scope...
410 let r = self.module(db).resolver(db);
411 // ...and add generic params, if present
412 let p = self.generic_params(db);
413 let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
414 r.push_scope(Scope::AdtScope(self.into()))
415 }
416} 374}
417 375
418#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 376#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -474,22 +432,52 @@ impl Adt {
474 } 432 }
475 } 433 }
476 434
435 pub fn module(self, db: &impl DefDatabase) -> Module {
436 match self {
437 Adt::Struct(s) => s.module(db),
438 Adt::Union(s) => s.module(db),
439 Adt::Enum(e) => e.module(db),
440 }
441 }
442
477 pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> { 443 pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
478 Some( 444 Some(self.module(db).krate())
479 match self { 445 }
480 Adt::Struct(s) => s.module(db), 446}
481 Adt::Union(s) => s.module(db), 447
482 Adt::Enum(e) => e.module(db), 448#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
483 } 449pub enum VariantDef {
484 .krate(), 450 Struct(Struct),
485 ) 451 EnumVariant(EnumVariant),
452}
453impl_froms!(VariantDef: Struct, EnumVariant);
454
455impl VariantDef {
456 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
457 match self {
458 VariantDef::Struct(it) => it.fields(db),
459 VariantDef::EnumVariant(it) => it.fields(db),
460 }
461 }
462
463 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
464 match self {
465 VariantDef::Struct(it) => it.field(db, name),
466 VariantDef::EnumVariant(it) => it.field(db, name),
467 }
468 }
469
470 pub fn module(self, db: &impl HirDatabase) -> Module {
471 match self {
472 VariantDef::Struct(it) => it.module(db),
473 VariantDef::EnumVariant(it) => it.module(db),
474 }
486 } 475 }
487 476
488 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { 477 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
489 match self { 478 match self {
490 Adt::Struct(it) => it.resolver(db), 479 VariantDef::Struct(it) => it.variant_data(db),
491 Adt::Union(it) => it.resolver(db), 480 VariantDef::EnumVariant(it) => it.variant_data(db),
492 Adt::Enum(it) => it.resolver(db),
493 } 481 }
494 } 482 }
495} 483}
@@ -505,15 +493,6 @@ pub enum DefWithBody {
505impl_froms!(DefWithBody: Function, Const, Static); 493impl_froms!(DefWithBody: Function, Const, Static);
506 494
507impl DefWithBody { 495impl DefWithBody {
508 /// Builds a resolver for code inside this item.
509 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
510 match self {
511 DefWithBody::Const(c) => c.resolver(db),
512 DefWithBody::Function(f) => f.resolver(db),
513 DefWithBody::Static(s) => s.resolver(db),
514 }
515 }
516
517 pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> { 496 pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
518 match self { 497 match self {
519 DefWithBody::Const(c) => c.krate(db), 498 DefWithBody::Const(c) => c.krate(db),
@@ -598,10 +577,10 @@ impl FnData {
598 func: Function, 577 func: Function,
599 ) -> Arc<FnData> { 578 ) -> Arc<FnData> {
600 let src = func.source(db); 579 let src = func.source(db);
601 let name = src.ast.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); 580 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
602 let mut params = Vec::new(); 581 let mut params = Vec::new();
603 let mut has_self_param = false; 582 let mut has_self_param = false;
604 if let Some(param_list) = src.ast.param_list() { 583 if let Some(param_list) = src.value.param_list() {
605 if let Some(self_param) = param_list.self_param() { 584 if let Some(self_param) = param_list.self_param() {
606 let self_type = if let Some(type_ref) = self_param.ascribed_type() { 585 let self_type = if let Some(type_ref) = self_param.ascribed_type() {
607 TypeRef::from_ast(type_ref) 586 TypeRef::from_ast(type_ref)
@@ -625,7 +604,7 @@ impl FnData {
625 params.push(type_ref); 604 params.push(type_ref);
626 } 605 }
627 } 606 }
628 let ret_type = if let Some(type_ref) = src.ast.ret_type().and_then(|rt| rt.type_ref()) { 607 let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
629 TypeRef::from_ast(type_ref) 608 TypeRef::from_ast(type_ref)
630 } else { 609 } else {
631 TypeRef::unit() 610 TypeRef::unit()
@@ -655,7 +634,7 @@ impl FnData {
655 634
656impl Function { 635impl Function {
657 pub fn module(self, db: &impl DefDatabase) -> Module { 636 pub fn module(self, db: &impl DefDatabase) -> Module {
658 Module { id: self.id.module(db) } 637 self.id.lookup(db).module(db).into()
659 } 638 }
660 639
661 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 640 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -688,35 +667,28 @@ impl Function {
688 667
689 /// The containing impl block, if this is a method. 668 /// The containing impl block, if this is a method.
690 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { 669 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
691 ImplBlock::containing(db, self.into()) 670 match self.container(db) {
671 Some(Container::ImplBlock(it)) => Some(it),
672 _ => None,
673 }
692 } 674 }
693 675
694 /// The containing trait, if this is a trait method definition. 676 /// The containing trait, if this is a trait method definition.
695 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { 677 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
696 db.trait_items_index(self.module(db)).get_parent_trait(self.into()) 678 match self.container(db) {
679 Some(Container::Trait(it)) => Some(it),
680 _ => None,
681 }
697 } 682 }
698 683
699 pub fn container(self, db: &impl DefDatabase) -> Option<Container> { 684 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
700 if let Some(impl_block) = self.impl_block(db) { 685 match self.id.lookup(db).container {
701 Some(impl_block.into()) 686 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
702 } else if let Some(trait_) = self.parent_trait(db) { 687 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
703 Some(trait_.into()) 688 ContainerId::ModuleId(_) => None,
704 } else {
705 None
706 } 689 }
707 } 690 }
708 691
709 // FIXME: move to a more general type for 'body-having' items
710 /// Builds a resolver for code inside this item.
711 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
712 // take the outer scope...
713 let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db));
714 // ...and add generic params, if present
715 let p = self.generic_params(db);
716 let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
717 r
718 }
719
720 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { 692 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
721 let infer = self.infer(db); 693 let infer = self.infer(db);
722 infer.add_diagnostics(db, self, sink); 694 infer.add_diagnostics(db, self, sink);
@@ -732,7 +704,7 @@ pub struct Const {
732 704
733impl Const { 705impl Const {
734 pub fn module(self, db: &impl DefDatabase) -> Module { 706 pub fn module(self, db: &impl DefDatabase) -> Module {
735 Module { id: self.id.module(db) } 707 Module { id: self.id.lookup(db).module(db) }
736 } 708 }
737 709
738 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 710 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -751,35 +723,29 @@ impl Const {
751 db.infer(self.into()) 723 db.infer(self.into())
752 } 724 }
753 725
754 /// The containing impl block, if this is a method. 726 /// The containing impl block, if this is a type alias.
755 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { 727 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
756 ImplBlock::containing(db, self.into()) 728 match self.container(db) {
729 Some(Container::ImplBlock(it)) => Some(it),
730 _ => None,
731 }
757 } 732 }
758 733
734 /// The containing trait, if this is a trait type alias definition.
759 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { 735 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
760 db.trait_items_index(self.module(db)).get_parent_trait(self.into()) 736 match self.container(db) {
737 Some(Container::Trait(it)) => Some(it),
738 _ => None,
739 }
761 } 740 }
762 741
763 pub fn container(self, db: &impl DefDatabase) -> Option<Container> { 742 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
764 if let Some(impl_block) = self.impl_block(db) { 743 match self.id.lookup(db).container {
765 Some(impl_block.into()) 744 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
766 } else if let Some(trait_) = self.parent_trait(db) { 745 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
767 Some(trait_.into()) 746 ContainerId::ModuleId(_) => None,
768 } else {
769 None
770 } 747 }
771 } 748 }
772
773 // FIXME: move to a more general type for 'body-having' items
774 /// Builds a resolver for code inside this item.
775 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
776 // take the outer scope...
777 let r = self
778 .impl_block(db)
779 .map(|ib| ib.resolver(db))
780 .unwrap_or_else(|| self.module(db).resolver(db));
781 r
782 }
783} 749}
784 750
785#[derive(Debug, Clone, PartialEq, Eq)] 751#[derive(Debug, Clone, PartialEq, Eq)]
@@ -801,7 +767,7 @@ impl ConstData {
801 db: &(impl DefDatabase + AstDatabase), 767 db: &(impl DefDatabase + AstDatabase),
802 konst: Const, 768 konst: Const,
803 ) -> Arc<ConstData> { 769 ) -> Arc<ConstData> {
804 let node = konst.source(db).ast; 770 let node = konst.source(db).value;
805 const_data_for(&node) 771 const_data_for(&node)
806 } 772 }
807 773
@@ -809,7 +775,7 @@ impl ConstData {
809 db: &(impl DefDatabase + AstDatabase), 775 db: &(impl DefDatabase + AstDatabase),
810 konst: Static, 776 konst: Static,
811 ) -> Arc<ConstData> { 777 ) -> Arc<ConstData> {
812 let node = konst.source(db).ast; 778 let node = konst.source(db).value;
813 const_data_for(&node) 779 const_data_for(&node)
814 } 780 }
815} 781}
@@ -839,12 +805,6 @@ impl Static {
839 db.static_data(self) 805 db.static_data(self)
840 } 806 }
841 807
842 /// Builds a resolver for code inside this item.
843 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
844 // take the outer scope...
845 self.module(db).resolver(db)
846 }
847
848 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 808 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
849 db.infer(self.into()) 809 db.infer(self.into())
850 } 810 }
@@ -861,11 +821,11 @@ impl Trait {
861 } 821 }
862 822
863 pub fn name(self, db: &impl DefDatabase) -> Option<Name> { 823 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
864 self.trait_data(db).name().clone() 824 self.trait_data(db).name.clone()
865 } 825 }
866 826
867 pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { 827 pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> {
868 self.trait_data(db).items().to_vec() 828 self.trait_data(db).items.iter().map(|it| (*it).into()).collect()
869 } 829 }
870 830
871 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { 831 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
@@ -912,10 +872,10 @@ impl Trait {
912 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { 872 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
913 let trait_data = self.trait_data(db); 873 let trait_data = self.trait_data(db);
914 trait_data 874 trait_data
915 .items() 875 .items
916 .iter() 876 .iter()
917 .filter_map(|item| match item { 877 .filter_map(|item| match item {
918 AssocItem::TypeAlias(t) => Some(*t), 878 AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)),
919 _ => None, 879 _ => None,
920 }) 880 })
921 .find(|t| &t.name(db) == name) 881 .find(|t| &t.name(db) == name)
@@ -930,7 +890,7 @@ impl Trait {
930 } 890 }
931 891
932 pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { 892 pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> {
933 db.trait_data(self) 893 db.trait_data(self.id)
934 } 894 }
935 895
936 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { 896 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {
@@ -938,15 +898,7 @@ impl Trait {
938 } 898 }
939 899
940 pub fn is_auto(self, db: &impl DefDatabase) -> bool { 900 pub fn is_auto(self, db: &impl DefDatabase) -> bool {
941 self.trait_data(db).is_auto() 901 self.trait_data(db).auto
942 }
943
944 pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
945 let r = self.module(db).resolver(db);
946 // add generic params, if present
947 let p = self.generic_params(db);
948 let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
949 r
950 } 902 }
951} 903}
952 904
@@ -957,30 +909,34 @@ pub struct TypeAlias {
957 909
958impl TypeAlias { 910impl TypeAlias {
959 pub fn module(self, db: &impl DefDatabase) -> Module { 911 pub fn module(self, db: &impl DefDatabase) -> Module {
960 Module { id: self.id.module(db) } 912 Module { id: self.id.lookup(db).module(db) }
961 } 913 }
962 914
963 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 915 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
964 Some(self.module(db).krate()) 916 Some(self.module(db).krate())
965 } 917 }
966 918
967 /// The containing impl block, if this is a method. 919 /// The containing impl block, if this is a type alias.
968 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { 920 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
969 ImplBlock::containing(db, self.into()) 921 match self.container(db) {
922 Some(Container::ImplBlock(it)) => Some(it),
923 _ => None,
924 }
970 } 925 }
971 926
972 /// The containing trait, if this is a trait method definition. 927 /// The containing trait, if this is a trait type alias definition.
973 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { 928 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
974 db.trait_items_index(self.module(db)).get_parent_trait(self.into()) 929 match self.container(db) {
930 Some(Container::Trait(it)) => Some(it),
931 _ => None,
932 }
975 } 933 }
976 934
977 pub fn container(self, db: &impl DefDatabase) -> Option<Container> { 935 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
978 if let Some(impl_block) = self.impl_block(db) { 936 match self.id.lookup(db).container {
979 Some(impl_block.into()) 937 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
980 } else if let Some(trait_) = self.parent_trait(db) { 938 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
981 Some(trait_.into()) 939 ContainerId::ModuleId(_) => None,
982 } else {
983 None
984 } 940 }
985 } 941 }
986 942
@@ -995,19 +951,6 @@ impl TypeAlias {
995 pub fn name(self, db: &impl DefDatabase) -> Name { 951 pub fn name(self, db: &impl DefDatabase) -> Name {
996 db.type_alias_data(self).name.clone() 952 db.type_alias_data(self).name.clone()
997 } 953 }
998
999 /// Builds a resolver for the type references in this type alias.
1000 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
1001 // take the outer scope...
1002 let r = self
1003 .impl_block(db)
1004 .map(|ib| ib.resolver(db))
1005 .unwrap_or_else(|| self.module(db).resolver(db));
1006 // ...and add generic params, if present
1007 let p = self.generic_params(db);
1008 let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
1009 r
1010 }
1011} 954}
1012 955
1013#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 956#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -1023,15 +966,6 @@ pub enum Container {
1023} 966}
1024impl_froms!(Container: Trait, ImplBlock); 967impl_froms!(Container: Trait, ImplBlock);
1025 968
1026impl Container {
1027 pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
1028 match self {
1029 Container::Trait(trait_) => trait_.resolver(db),
1030 Container::ImplBlock(impl_block) => impl_block.resolver(db),
1031 }
1032 }
1033}
1034
1035#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 969#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1036pub enum AssocItem { 970pub enum AssocItem {
1037 Function(Function), 971 Function(Function),
diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs
index f7db36b66..9e304217c 100644
--- a/crates/ra_hir/src/code_model/attrs.rs
+++ b/crates/ra_hir/src/code_model/attrs.rs
@@ -49,9 +49,9 @@ pub(crate) fn attributes_query(
49 AttrDef::Module(it) => { 49 AttrDef::Module(it) => {
50 let src = it.declaration_source(db)?; 50 let src = it.declaration_source(db)?;
51 let hygiene = Hygiene::new(db, src.file_id); 51 let hygiene = Hygiene::new(db, src.file_id);
52 Attr::from_attrs_owner(&src.ast, &hygiene) 52 Attr::from_attrs_owner(&src.value, &hygiene)
53 } 53 }
54 AttrDef::StructField(it) => match it.source(db).ast { 54 AttrDef::StructField(it) => match it.source(db).value {
55 FieldSource::Named(named) => { 55 FieldSource::Named(named) => {
56 let src = it.source(db); 56 let src = it.source(db);
57 let hygiene = Hygiene::new(db, src.file_id); 57 let hygiene = Hygiene::new(db, src.file_id);
@@ -82,7 +82,7 @@ where
82{ 82{
83 let src = node.source(db); 83 let src = node.source(db);
84 let hygiene = Hygiene::new(db, src.file_id); 84 let hygiene = Hygiene::new(db, src.file_id);
85 Attr::from_attrs_owner(&src.ast, &hygiene) 85 Attr::from_attrs_owner(&src.value, &hygiene)
86} 86}
87 87
88impl<T: Into<AttrDef> + Copy> Attrs for T { 88impl<T: Into<AttrDef> + Copy> Attrs for T {
diff --git a/crates/ra_hir/src/code_model/docs.rs b/crates/ra_hir/src/code_model/docs.rs
index 8533b4f5e..e40efef34 100644
--- a/crates/ra_hir/src/code_model/docs.rs
+++ b/crates/ra_hir/src/code_model/docs.rs
@@ -70,23 +70,23 @@ pub(crate) fn documentation_query(
70 def: DocDef, 70 def: DocDef,
71) -> Option<Documentation> { 71) -> Option<Documentation> {
72 match def { 72 match def {
73 DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.ast), 73 DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.value),
74 DocDef::StructField(it) => match it.source(db).ast { 74 DocDef::StructField(it) => match it.source(db).value {
75 FieldSource::Named(named) => docs_from_ast(&named), 75 FieldSource::Named(named) => docs_from_ast(&named),
76 FieldSource::Pos(..) => None, 76 FieldSource::Pos(..) => None,
77 }, 77 },
78 DocDef::Adt(it) => match it { 78 DocDef::Adt(it) => match it {
79 Adt::Struct(it) => docs_from_ast(&it.source(db).ast), 79 Adt::Struct(it) => docs_from_ast(&it.source(db).value),
80 Adt::Enum(it) => docs_from_ast(&it.source(db).ast), 80 Adt::Enum(it) => docs_from_ast(&it.source(db).value),
81 Adt::Union(it) => docs_from_ast(&it.source(db).ast), 81 Adt::Union(it) => docs_from_ast(&it.source(db).value),
82 }, 82 },
83 DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).ast), 83 DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).value),
84 DocDef::Static(it) => docs_from_ast(&it.source(db).ast), 84 DocDef::Static(it) => docs_from_ast(&it.source(db).value),
85 DocDef::Const(it) => docs_from_ast(&it.source(db).ast), 85 DocDef::Const(it) => docs_from_ast(&it.source(db).value),
86 DocDef::Function(it) => docs_from_ast(&it.source(db).ast), 86 DocDef::Function(it) => docs_from_ast(&it.source(db).value),
87 DocDef::Trait(it) => docs_from_ast(&it.source(db).ast), 87 DocDef::Trait(it) => docs_from_ast(&it.source(db).value),
88 DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).ast), 88 DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).value),
89 DocDef::MacroDef(it) => docs_from_ast(&it.source(db).ast), 89 DocDef::MacroDef(it) => docs_from_ast(&it.source(db).value),
90 } 90 }
91} 91}
92 92
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index 247ae3e55..4aa427de4 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -1,13 +1,13 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{HasSource as _, Lookup};
3use ra_syntax::ast::{self, AstNode}; 4use ra_syntax::ast::{self, AstNode};
4 5
5use crate::{ 6use crate::{
6 adt::VariantDef,
7 db::{AstDatabase, DefDatabase, HirDatabase}, 7 db::{AstDatabase, DefDatabase, HirDatabase},
8 ids::AstItemDef, 8 ids::AstItemDef,
9 Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module, 9 Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module,
10 ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, 10 ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef,
11}; 11};
12 12
13pub use hir_expand::Source; 13pub use hir_expand::Source;
@@ -25,9 +25,9 @@ impl Module {
25 let def_map = db.crate_def_map(self.id.krate); 25 let def_map = db.crate_def_map(self.id.krate);
26 let decl_id = def_map[self.id.module_id].declaration; 26 let decl_id = def_map[self.id.module_id].declaration;
27 let file_id = def_map[self.id.module_id].definition; 27 let file_id = def_map[self.id.module_id].definition;
28 let ast = ModuleSource::new(db, file_id, decl_id); 28 let value = ModuleSource::new(db, file_id, decl_id);
29 let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); 29 let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id());
30 Source { file_id, ast } 30 Source { file_id, value }
31 } 31 }
32 32
33 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. 33 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
@@ -38,8 +38,8 @@ impl Module {
38 ) -> Option<Source<ast::Module>> { 38 ) -> Option<Source<ast::Module>> {
39 let def_map = db.crate_def_map(self.id.krate); 39 let def_map = db.crate_def_map(self.id.krate);
40 let decl = def_map[self.id.module_id].declaration?; 40 let decl = def_map[self.id.module_id].declaration?;
41 let ast = decl.to_node(db); 41 let value = decl.to_node(db);
42 Some(Source { file_id: decl.file_id(), ast }) 42 Some(Source { file_id: decl.file_id(), value })
43 } 43 }
44} 44}
45 45
@@ -53,11 +53,11 @@ impl HasSource for StructField {
53 let (file_id, struct_kind) = match self.parent { 53 let (file_id, struct_kind) = match self.parent {
54 VariantDef::Struct(s) => { 54 VariantDef::Struct(s) => {
55 ss = s.source(db); 55 ss = s.source(db);
56 (ss.file_id, ss.ast.kind()) 56 (ss.file_id, ss.value.kind())
57 } 57 }
58 VariantDef::EnumVariant(e) => { 58 VariantDef::EnumVariant(e) => {
59 es = e.source(db); 59 es = e.source(db);
60 (es.file_id, es.ast.kind()) 60 (es.file_id, es.value.kind())
61 } 61 }
62 }; 62 };
63 63
@@ -66,13 +66,13 @@ impl HasSource for StructField {
66 ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(), 66 ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(),
67 ast::StructKind::Unit => Vec::new(), 67 ast::StructKind::Unit => Vec::new(),
68 }; 68 };
69 let ast = field_sources 69 let value = field_sources
70 .into_iter() 70 .into_iter()
71 .zip(fields.iter()) 71 .zip(fields.iter())
72 .find(|(_syntax, (id, _))| *id == self.id) 72 .find(|(_syntax, (id, _))| *id == self.id)
73 .unwrap() 73 .unwrap()
74 .0; 74 .0;
75 Source { file_id, ast } 75 Source { file_id, value }
76 } 76 }
77} 77}
78impl HasSource for Struct { 78impl HasSource for Struct {
@@ -98,8 +98,8 @@ impl HasSource for EnumVariant {
98 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> { 98 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> {
99 let enum_data = db.enum_data(self.parent.id); 99 let enum_data = db.enum_data(self.parent.id);
100 let src = self.parent.id.source(db); 100 let src = self.parent.id.source(db);
101 let ast = src 101 let value = src
102 .ast 102 .value
103 .variant_list() 103 .variant_list()
104 .into_iter() 104 .into_iter()
105 .flat_map(|it| it.variants()) 105 .flat_map(|it| it.variants())
@@ -107,19 +107,19 @@ impl HasSource for EnumVariant {
107 .find(|(_syntax, (id, _))| *id == self.id) 107 .find(|(_syntax, (id, _))| *id == self.id)
108 .unwrap() 108 .unwrap()
109 .0; 109 .0;
110 Source { file_id: src.file_id, ast } 110 Source { file_id: src.file_id, value }
111 } 111 }
112} 112}
113impl HasSource for Function { 113impl HasSource for Function {
114 type Ast = ast::FnDef; 114 type Ast = ast::FnDef;
115 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { 115 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> {
116 self.id.source(db) 116 self.id.lookup(db).source(db)
117 } 117 }
118} 118}
119impl HasSource for Const { 119impl HasSource for Const {
120 type Ast = ast::ConstDef; 120 type Ast = ast::ConstDef;
121 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> { 121 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> {
122 self.id.source(db) 122 self.id.lookup(db).source(db)
123 } 123 }
124} 124}
125impl HasSource for Static { 125impl HasSource for Static {
@@ -137,13 +137,13 @@ impl HasSource for Trait {
137impl HasSource for TypeAlias { 137impl HasSource for TypeAlias {
138 type Ast = ast::TypeAliasDef; 138 type Ast = ast::TypeAliasDef;
139 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { 139 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> {
140 self.id.source(db) 140 self.id.lookup(db).source(db)
141 } 141 }
142} 142}
143impl HasSource for MacroDef { 143impl HasSource for MacroDef {
144 type Ast = ast::MacroCall; 144 type Ast = ast::MacroCall;
145 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::MacroCall> { 145 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::MacroCall> {
146 Source { file_id: self.id.ast_id.file_id(), ast: self.id.ast_id.to_node(db) } 146 Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) }
147 } 147 }
148} 148}
149 149
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index d75d71d66..a9982a70f 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -8,10 +8,9 @@ use ra_syntax::SmolStr;
8 8
9use crate::{ 9use crate::{
10 debug::HirDebugDatabase, 10 debug::HirDebugDatabase,
11 generics::{GenericDef, GenericParams}, 11 generics::GenericDef,
12 ids, 12 ids,
13 lang_item::{LangItemTarget, LangItems}, 13 lang_item::{LangItemTarget, LangItems},
14 traits::TraitData,
15 ty::{ 14 ty::{
16 method_resolution::CrateImplBlocks, 15 method_resolution::CrateImplBlocks,
17 traits::{AssocTyValue, Impl}, 16 traits::{AssocTyValue, Impl},
@@ -25,8 +24,9 @@ use crate::{
25 24
26pub use hir_def::db::{ 25pub use hir_def::db::{
27 BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, 26 BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
28 EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, 27 EnumDataQuery, ExprScopesQuery, GenericParamsQuery, ImplDataQuery, InternDatabase,
29 RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, 28 InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery,
29 TraitDataQuery,
30}; 30};
31pub use hir_expand::db::{ 31pub use hir_expand::db::{
32 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 32 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
@@ -37,15 +37,6 @@ pub use hir_expand::db::{
37#[salsa::query_group(DefDatabaseStorage)] 37#[salsa::query_group(DefDatabaseStorage)]
38#[salsa::requires(AstDatabase)] 38#[salsa::requires(AstDatabase)]
39pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { 39pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
40 #[salsa::invoke(crate::traits::TraitData::trait_data_query)]
41 fn trait_data(&self, t: Trait) -> Arc<TraitData>;
42
43 #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)]
44 fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex;
45
46 #[salsa::invoke(crate::generics::GenericParams::generic_params_query)]
47 fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>;
48
49 #[salsa::invoke(FnData::fn_data_query)] 40 #[salsa::invoke(FnData::fn_data_query)]
50 fn fn_data(&self, func: Function) -> Arc<FnData>; 41 fn fn_data(&self, func: Function) -> Arc<FnData>;
51 42
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs
index 1751e7be3..7d1b64858 100644
--- a/crates/ra_hir/src/diagnostics.rs
+++ b/crates/ra_hir/src/diagnostics.rs
@@ -21,7 +21,7 @@ impl Diagnostic for NoSuchField {
21 } 21 }
22 22
23 fn source(&self) -> Source<SyntaxNodePtr> { 23 fn source(&self) -> Source<SyntaxNodePtr> {
24 Source { file_id: self.file, ast: self.field.into() } 24 Source { file_id: self.file, value: self.field.into() }
25 } 25 }
26 26
27 fn as_any(&self) -> &(dyn Any + Send + 'static) { 27 fn as_any(&self) -> &(dyn Any + Send + 'static) {
@@ -41,7 +41,7 @@ impl Diagnostic for MissingFields {
41 "fill structure fields".to_string() 41 "fill structure fields".to_string()
42 } 42 }
43 fn source(&self) -> Source<SyntaxNodePtr> { 43 fn source(&self) -> Source<SyntaxNodePtr> {
44 Source { file_id: self.file, ast: self.field_list.into() } 44 Source { file_id: self.file, value: self.field_list.into() }
45 } 45 }
46 fn as_any(&self) -> &(dyn Any + Send + 'static) { 46 fn as_any(&self) -> &(dyn Any + Send + 'static) {
47 self 47 self
@@ -53,7 +53,7 @@ impl AstDiagnostic for MissingFields {
53 53
54 fn ast(&self, db: &impl AstDatabase) -> Self::AST { 54 fn ast(&self, db: &impl AstDatabase) -> Self::AST {
55 let root = db.parse_or_expand(self.source().file_id).unwrap(); 55 let root = db.parse_or_expand(self.source().file_id).unwrap();
56 let node = self.source().ast.to_node(&root); 56 let node = self.source().value.to_node(&root);
57 ast::RecordFieldList::cast(node).unwrap() 57 ast::RecordFieldList::cast(node).unwrap()
58 } 58 }
59} 59}
@@ -69,7 +69,7 @@ impl Diagnostic for MissingOkInTailExpr {
69 "wrap return expression in Ok".to_string() 69 "wrap return expression in Ok".to_string()
70 } 70 }
71 fn source(&self) -> Source<SyntaxNodePtr> { 71 fn source(&self) -> Source<SyntaxNodePtr> {
72 Source { file_id: self.file, ast: self.expr.into() } 72 Source { file_id: self.file, value: self.expr.into() }
73 } 73 }
74 fn as_any(&self) -> &(dyn Any + Send + 'static) { 74 fn as_any(&self) -> &(dyn Any + Send + 'static) {
75 self 75 self
@@ -81,7 +81,7 @@ impl AstDiagnostic for MissingOkInTailExpr {
81 81
82 fn ast(&self, db: &impl AstDatabase) -> Self::AST { 82 fn ast(&self, db: &impl AstDatabase) -> Self::AST {
83 let root = db.parse_or_expand(self.file).unwrap(); 83 let root = db.parse_or_expand(self.file).unwrap();
84 let node = self.source().ast.to_node(&root); 84 let node = self.source().value.to_node(&root);
85 ast::Expr::cast(node).unwrap() 85 ast::Expr::cast(node).unwrap()
86 } 86 }
87} 87}
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index e3733779e..869879bdf 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -11,6 +11,7 @@ use rustc_hash::FxHashSet;
11use crate::{ 11use crate::{
12 db::HirDatabase, 12 db::HirDatabase,
13 diagnostics::{MissingFields, MissingOkInTailExpr}, 13 diagnostics::{MissingFields, MissingOkInTailExpr},
14 resolve::HasResolver,
14 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, 15 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor},
15 Adt, DefWithBody, Function, HasBody, Name, Path, Resolver, 16 Adt, DefWithBody, Function, HasBody, Name, Path, Resolver,
16}; 17};
@@ -116,7 +117,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
116 let source_map = self.func.body_source_map(db); 117 let source_map = self.func.body_source_map(db);
117 118
118 if let Some(source_ptr) = source_map.expr_syntax(id) { 119 if let Some(source_ptr) = source_map.expr_syntax(id) {
119 if let Some(expr) = source_ptr.ast.a() { 120 if let Some(expr) = source_ptr.value.a() {
120 let root = source_ptr.file_syntax(db); 121 let root = source_ptr.file_syntax(db);
121 if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) { 122 if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) {
122 if let Some(field_list) = record_lit.record_field_list() { 123 if let Some(field_list) = record_lit.record_field_list() {
@@ -161,7 +162,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
161 let source_map = self.func.body_source_map(db); 162 let source_map = self.func.body_source_map(db);
162 163
163 if let Some(source_ptr) = source_map.expr_syntax(id) { 164 if let Some(source_ptr) = source_map.expr_syntax(id) {
164 if let Some(expr) = source_ptr.ast.a() { 165 if let Some(expr) = source_ptr.value.a() {
165 self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr }); 166 self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr });
166 } 167 }
167 } 168 }
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs
index f2203e995..b7692d407 100644
--- a/crates/ra_hir/src/from_id.rs
+++ b/crates/ra_hir/src/from_id.rs
@@ -3,9 +3,9 @@
3//! It's unclear if we need this long-term, but it's definitelly useful while we 3//! It's unclear if we need this long-term, but it's definitelly useful while we
4//! are splitting the hir. 4//! are splitting the hir.
5 5
6use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, ModuleDefId}; 6use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId};
7 7
8use crate::{Adt, AssocItem, DefWithBody, EnumVariant, ModuleDef}; 8use crate::{Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef};
9 9
10macro_rules! from_id { 10macro_rules! from_id {
11 ($(($id:path, $ty:path)),*) => {$( 11 ($(($id:path, $ty:path)),*) => {$(
@@ -41,6 +41,16 @@ impl From<AdtId> for Adt {
41 } 41 }
42} 42}
43 43
44impl From<Adt> for AdtId {
45 fn from(id: Adt) -> Self {
46 match id {
47 Adt::Struct(it) => AdtId::StructId(it.id),
48 Adt::Union(it) => AdtId::UnionId(it.id),
49 Adt::Enum(it) => AdtId::EnumId(it.id),
50 }
51 }
52}
53
44impl From<EnumVariantId> for EnumVariant { 54impl From<EnumVariantId> for EnumVariant {
45 fn from(id: EnumVariantId) -> Self { 55 fn from(id: EnumVariantId) -> Self {
46 EnumVariant { parent: id.parent.into(), id: id.local_id } 56 EnumVariant { parent: id.parent.into(), id: id.local_id }
@@ -82,3 +92,33 @@ impl From<AssocItemId> for AssocItem {
82 } 92 }
83 } 93 }
84} 94}
95
96impl From<GenericDef> for GenericDefId {
97 fn from(def: GenericDef) -> Self {
98 match def {
99 GenericDef::Function(it) => GenericDefId::FunctionId(it.id),
100 GenericDef::Adt(it) => GenericDefId::AdtId(it.into()),
101 GenericDef::Trait(it) => GenericDefId::TraitId(it.id),
102 GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id),
103 GenericDef::ImplBlock(it) => GenericDefId::ImplId(it.id),
104 GenericDef::EnumVariant(it) => {
105 GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id })
106 }
107 GenericDef::Const(it) => GenericDefId::ConstId(it.id),
108 }
109 }
110}
111
112impl From<GenericDefId> for GenericDef {
113 fn from(def: GenericDefId) -> Self {
114 match def {
115 GenericDefId::FunctionId(it) => GenericDef::Function(it.into()),
116 GenericDefId::AdtId(it) => GenericDef::Adt(it.into()),
117 GenericDefId::TraitId(it) => GenericDef::Trait(it.into()),
118 GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
119 GenericDefId::ImplId(it) => GenericDef::ImplBlock(it.into()),
120 GenericDefId::EnumVariantId(it) => GenericDef::EnumVariant(it.into()),
121 GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
122 }
123 }
124}
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 1c26756c9..b86307c58 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -4,15 +4,15 @@ use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId};
4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, AstNode, NameOwner}, 6 ast::{self, AstNode, NameOwner},
7 match_ast, 7 match_ast, AstPtr, SyntaxNode,
8}; 8};
9 9
10use crate::{ 10use crate::{
11 db::{AstDatabase, DefDatabase, HirDatabase}, 11 db::{AstDatabase, DefDatabase, HirDatabase},
12 ids::{AstItemDef, LocationCtx}, 12 ids::{AstItemDef, LocationCtx},
13 Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, ImplBlock, 13 AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource,
14 Local, MacroDef, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, 14 ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct,
15 Union, VariantDef, 15 StructField, Trait, TypeAlias, Union, VariantDef,
16}; 16};
17 17
18pub trait FromSource: Sized { 18pub trait FromSource: Sized {
@@ -52,15 +52,54 @@ impl FromSource for Trait {
52impl FromSource for Function { 52impl FromSource for Function {
53 type Ast = ast::FnDef; 53 type Ast = ast::FnDef;
54 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 54 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
55 let id = from_source(db, src)?; 55 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
56 Some(Function { id }) 56 Container::Trait(it) => it.items(db),
57 Container::ImplBlock(it) => it.items(db),
58 Container::Module(m) => {
59 return m
60 .declarations(db)
61 .into_iter()
62 .filter_map(|it| match it {
63 ModuleDef::Function(it) => Some(it),
64 _ => None,
65 })
66 .find(|it| same_source(&it.source(db), &src))
67 }
68 };
69 items
70 .into_iter()
71 .filter_map(|it| match it {
72 AssocItem::Function(it) => Some(it),
73 _ => None,
74 })
75 .find(|it| same_source(&it.source(db), &src))
57 } 76 }
58} 77}
78
59impl FromSource for Const { 79impl FromSource for Const {
60 type Ast = ast::ConstDef; 80 type Ast = ast::ConstDef;
61 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 81 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
62 let id = from_source(db, src)?; 82 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
63 Some(Const { id }) 83 Container::Trait(it) => it.items(db),
84 Container::ImplBlock(it) => it.items(db),
85 Container::Module(m) => {
86 return m
87 .declarations(db)
88 .into_iter()
89 .filter_map(|it| match it {
90 ModuleDef::Const(it) => Some(it),
91 _ => None,
92 })
93 .find(|it| same_source(&it.source(db), &src))
94 }
95 };
96 items
97 .into_iter()
98 .filter_map(|it| match it {
99 AssocItem::Const(it) => Some(it),
100 _ => None,
101 })
102 .find(|it| same_source(&it.source(db), &src))
64 } 103 }
65} 104}
66impl FromSource for Static { 105impl FromSource for Static {
@@ -73,8 +112,27 @@ impl FromSource for Static {
73impl FromSource for TypeAlias { 112impl FromSource for TypeAlias {
74 type Ast = ast::TypeAliasDef; 113 type Ast = ast::TypeAliasDef;
75 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 114 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
76 let id = from_source(db, src)?; 115 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
77 Some(TypeAlias { id }) 116 Container::Trait(it) => it.items(db),
117 Container::ImplBlock(it) => it.items(db),
118 Container::Module(m) => {
119 return m
120 .declarations(db)
121 .into_iter()
122 .filter_map(|it| match it {
123 ModuleDef::TypeAlias(it) => Some(it),
124 _ => None,
125 })
126 .find(|it| same_source(&it.source(db), &src))
127 }
128 };
129 items
130 .into_iter()
131 .filter_map(|it| match it {
132 AssocItem::TypeAlias(it) => Some(it),
133 _ => None,
134 })
135 .find(|it| same_source(&it.source(db), &src))
78 } 136 }
79} 137}
80 138
@@ -87,7 +145,7 @@ impl FromSource for MacroDef {
87 let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; 145 let module = Module::from_definition(db, Source::new(src.file_id, module_src))?;
88 let krate = module.krate().crate_id(); 146 let krate = module.krate().crate_id();
89 147
90 let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.ast)); 148 let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value));
91 149
92 let id: MacroDefId = MacroDefId { krate, ast_id, kind }; 150 let id: MacroDefId = MacroDefId { krate, ast_id, kind };
93 Some(MacroDef { id }) 151 Some(MacroDef { id })
@@ -105,26 +163,26 @@ impl FromSource for ImplBlock {
105impl FromSource for EnumVariant { 163impl FromSource for EnumVariant {
106 type Ast = ast::EnumVariant; 164 type Ast = ast::EnumVariant;
107 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 165 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
108 let parent_enum = src.ast.parent_enum(); 166 let parent_enum = src.value.parent_enum();
109 let src_enum = Source { file_id: src.file_id, ast: parent_enum }; 167 let src_enum = Source { file_id: src.file_id, value: parent_enum };
110 let variants = Enum::from_source(db, src_enum)?.variants(db); 168 let variants = Enum::from_source(db, src_enum)?.variants(db);
111 variants.into_iter().find(|v| v.source(db) == src) 169 variants.into_iter().find(|v| same_source(&v.source(db), &src))
112 } 170 }
113} 171}
114 172
115impl FromSource for StructField { 173impl FromSource for StructField {
116 type Ast = FieldSource; 174 type Ast = FieldSource;
117 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 175 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
118 let variant_def: VariantDef = match src.ast { 176 let variant_def: VariantDef = match src.value {
119 FieldSource::Named(ref field) => { 177 FieldSource::Named(ref field) => {
120 let ast = field.syntax().ancestors().find_map(ast::StructDef::cast)?; 178 let value = field.syntax().ancestors().find_map(ast::StructDef::cast)?;
121 let src = Source { file_id: src.file_id, ast }; 179 let src = Source { file_id: src.file_id, value };
122 let def = Struct::from_source(db, src)?; 180 let def = Struct::from_source(db, src)?;
123 VariantDef::from(def) 181 VariantDef::from(def)
124 } 182 }
125 FieldSource::Pos(ref field) => { 183 FieldSource::Pos(ref field) => {
126 let ast = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; 184 let value = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?;
127 let src = Source { file_id: src.file_id, ast }; 185 let src = Source { file_id: src.file_id, value };
128 let def = EnumVariant::from_source(db, src)?; 186 let def = EnumVariant::from_source(db, src)?;
129 VariantDef::from(def) 187 VariantDef::from(def)
130 } 188 }
@@ -142,12 +200,12 @@ impl FromSource for StructField {
142impl Local { 200impl Local {
143 pub fn from_source(db: &impl HirDatabase, src: Source<ast::BindPat>) -> Option<Self> { 201 pub fn from_source(db: &impl HirDatabase, src: Source<ast::BindPat>) -> Option<Self> {
144 let file_id = src.file_id; 202 let file_id = src.file_id;
145 let parent: DefWithBody = src.ast.syntax().ancestors().find_map(|it| { 203 let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| {
146 let res = match_ast! { 204 let res = match_ast! {
147 match it { 205 match it {
148 ast::ConstDef(ast) => { Const::from_source(db, Source { ast, file_id})?.into() }, 206 ast::ConstDef(value) => { Const::from_source(db, Source { value, file_id})?.into() },
149 ast::StaticDef(ast) => { Static::from_source(db, Source { ast, file_id})?.into() }, 207 ast::StaticDef(value) => { Static::from_source(db, Source { value, file_id})?.into() },
150 ast::FnDef(ast) => { Function::from_source(db, Source { ast, file_id})?.into() }, 208 ast::FnDef(value) => { Function::from_source(db, Source { value, file_id})?.into() },
151 _ => return None, 209 _ => return None,
152 } 210 }
153 }; 211 };
@@ -162,33 +220,33 @@ impl Local {
162 220
163impl Module { 221impl Module {
164 pub fn from_declaration(db: &impl DefDatabase, src: Source<ast::Module>) -> Option<Self> { 222 pub fn from_declaration(db: &impl DefDatabase, src: Source<ast::Module>) -> Option<Self> {
165 let parent_declaration = src.ast.syntax().ancestors().skip(1).find_map(ast::Module::cast); 223 let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
166 224
167 let parent_module = match parent_declaration { 225 let parent_module = match parent_declaration {
168 Some(parent_declaration) => { 226 Some(parent_declaration) => {
169 let src_parent = Source { file_id: src.file_id, ast: parent_declaration }; 227 let src_parent = Source { file_id: src.file_id, value: parent_declaration };
170 Module::from_declaration(db, src_parent) 228 Module::from_declaration(db, src_parent)
171 } 229 }
172 _ => { 230 _ => {
173 let src_parent = Source { 231 let src_parent = Source {
174 file_id: src.file_id, 232 file_id: src.file_id,
175 ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), 233 value: ModuleSource::new(db, Some(src.file_id.original_file(db)), None),
176 }; 234 };
177 Module::from_definition(db, src_parent) 235 Module::from_definition(db, src_parent)
178 } 236 }
179 }?; 237 }?;
180 238
181 let child_name = src.ast.name()?; 239 let child_name = src.value.name()?;
182 parent_module.child(db, &child_name.as_name()) 240 parent_module.child(db, &child_name.as_name())
183 } 241 }
184 242
185 pub fn from_definition(db: &impl DefDatabase, src: Source<ModuleSource>) -> Option<Self> { 243 pub fn from_definition(db: &impl DefDatabase, src: Source<ModuleSource>) -> Option<Self> {
186 match src.ast { 244 match src.value {
187 ModuleSource::Module(ref module) => { 245 ModuleSource::Module(ref module) => {
188 assert!(!module.has_semi()); 246 assert!(!module.has_semi());
189 return Module::from_declaration( 247 return Module::from_declaration(
190 db, 248 db,
191 Source { file_id: src.file_id, ast: module.clone() }, 249 Source { file_id: src.file_id, value: module.clone() },
192 ); 250 );
193 } 251 }
194 ModuleSource::SourceFile(_) => (), 252 ModuleSource::SourceFile(_) => (),
@@ -214,5 +272,47 @@ where
214 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); 272 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
215 let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; 273 let module = Module::from_definition(db, Source::new(src.file_id, module_src))?;
216 let ctx = LocationCtx::new(db, module.id, src.file_id); 274 let ctx = LocationCtx::new(db, module.id, src.file_id);
217 Some(DEF::from_ast(ctx, &src.ast)) 275 Some(DEF::from_ast(ctx, &src.value))
276}
277
278enum Container {
279 Trait(Trait),
280 ImplBlock(ImplBlock),
281 Module(Module),
282}
283
284impl Container {
285 fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option<Container> {
286 // FIXME: this doesn't try to handle nested declarations
287 for container in src.value.ancestors() {
288 let res = match_ast! {
289 match container {
290 ast::TraitDef(it) => {
291 let c = Trait::from_source(db, src.with_value(it))?;
292 Container::Trait(c)
293 },
294 ast::ImplBlock(it) => {
295 let c = ImplBlock::from_source(db, src.with_value(it))?;
296 Container::ImplBlock(c)
297 },
298 _ => { continue },
299 }
300 };
301 return Some(res);
302 }
303
304 let module_source = ModuleSource::from_child_node(db, src);
305 let c = Module::from_definition(db, src.with_value(module_source))?;
306 Some(Container::Module(c))
307 }
308}
309
310/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
311/// equal if they point to exactly the same object.
312///
313/// In general, we do not guarantee that we have exactly one instance of a
314/// syntax tree for each file. We probably should add such guarantee, but, for
315/// the time being, we will use identity-less AstPtr comparison.
316fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool {
317 s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new)
218} 318}
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
index c35482ae8..f1bf2ee9d 100644
--- a/crates/ra_hir/src/generics.rs
+++ b/crates/ra_hir/src/generics.rs
@@ -1,50 +1,12 @@
1//! Many kinds of items or constructs can have generic parameters: functions, 1//! Temp module to wrap hir_def::generics
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
6use std::sync::Arc; 2use std::sync::Arc;
7 3
8use hir_def::{
9 path::Path,
10 type_ref::{TypeBound, TypeRef},
11};
12use hir_expand::name::{self, AsName};
13use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner};
14
15use crate::{ 4use crate::{
16 db::{AstDatabase, DefDatabase, HirDatabase}, 5 db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait,
17 Adt, Const, Container, Enum, EnumVariant, Function, HasSource, ImplBlock, Name, Struct, Trait,
18 TypeAlias, Union, 6 TypeAlias, Union,
19}; 7};
20 8
21/// Data about a generic parameter (to a function, struct, impl, ...). 9pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate};
22#[derive(Clone, PartialEq, Eq, Debug)]
23pub struct GenericParam {
24 // FIXME: give generic params proper IDs
25 pub idx: u32,
26 pub name: Name,
27 pub default: Option<Path>,
28}
29
30/// Data about the generic parameters of a function, struct, impl, etc.
31#[derive(Clone, PartialEq, Eq, Debug)]
32pub struct GenericParams {
33 pub(crate) def: GenericDef,
34 pub(crate) parent_params: Option<Arc<GenericParams>>,
35 pub(crate) params: Vec<GenericParam>,
36 pub(crate) where_predicates: Vec<WherePredicate>,
37}
38
39/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
40/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
41/// It might still result in multiple actual predicates though, because of
42/// associated type bindings like `Iterator<Item = u32>`.
43#[derive(Clone, PartialEq, Eq, Debug)]
44pub struct WherePredicate {
45 pub(crate) type_ref: TypeRef,
46 pub(crate) bound: TypeBound,
47}
48 10
49#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 11#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
50pub enum GenericDef { 12pub enum GenericDef {
@@ -69,150 +31,6 @@ impl_froms!(
69 Const 31 Const
70); 32);
71 33
72impl GenericParams {
73 pub(crate) fn generic_params_query(
74 db: &(impl DefDatabase + AstDatabase),
75 def: GenericDef,
76 ) -> Arc<GenericParams> {
77 let parent = match def {
78 GenericDef::Function(it) => it.container(db).map(GenericDef::from),
79 GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from),
80 GenericDef::Const(it) => it.container(db).map(GenericDef::from),
81 GenericDef::EnumVariant(it) => Some(it.parent_enum(db).into()),
82 GenericDef::Adt(_) | GenericDef::Trait(_) => None,
83 GenericDef::ImplBlock(_) => None,
84 };
85 let mut generics = GenericParams {
86 def,
87 params: Vec::new(),
88 parent_params: parent.map(|p| db.generic_params(p)),
89 where_predicates: Vec::new(),
90 };
91 let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
92 // FIXME: add `: Sized` bound for everything except for `Self` in traits
93 match def {
94 GenericDef::Function(it) => generics.fill(&it.source(db).ast, start),
95 GenericDef::Adt(Adt::Struct(it)) => generics.fill(&it.source(db).ast, start),
96 GenericDef::Adt(Adt::Union(it)) => generics.fill(&it.source(db).ast, start),
97 GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).ast, start),
98 GenericDef::Trait(it) => {
99 // traits get the Self type as an implicit first type parameter
100 generics.params.push(GenericParam {
101 idx: start,
102 name: name::SELF_TYPE,
103 default: None,
104 });
105 generics.fill(&it.source(db).ast, start + 1);
106 // add super traits as bounds on Self
107 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
108 let self_param = TypeRef::Path(name::SELF_TYPE.into());
109 generics.fill_bounds(&it.source(db).ast, self_param);
110 }
111 GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start),
112 // Note that we don't add `Self` here: in `impl`s, `Self` is not a
113 // type-parameter, but rather is a type-alias for impl's target
114 // type, so this is handled by the resolver.
115 GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start),
116 GenericDef::EnumVariant(_) | GenericDef::Const(_) => {}
117 }
118
119 Arc::new(generics)
120 }
121
122 fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) {
123 if let Some(params) = node.type_param_list() {
124 self.fill_params(params, start)
125 }
126 if let Some(where_clause) = node.where_clause() {
127 self.fill_where_predicates(where_clause);
128 }
129 }
130
131 fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) {
132 for bound in
133 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
134 {
135 self.add_where_predicate_from_bound(bound, type_ref.clone());
136 }
137 }
138
139 fn fill_params(&mut self, params: ast::TypeParamList, start: u32) {
140 for (idx, type_param) in params.type_params().enumerate() {
141 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
142 // FIXME: Use `Path::from_src`
143 let default = type_param.default_type().and_then(|t| t.path()).and_then(Path::from_ast);
144
145 let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default };
146 self.params.push(param);
147
148 let type_ref = TypeRef::Path(name.into());
149 self.fill_bounds(&type_param, type_ref);
150 }
151 }
152
153 fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) {
154 for pred in where_clause.predicates() {
155 let type_ref = match pred.type_ref() {
156 Some(type_ref) => type_ref,
157 None => continue,
158 };
159 let type_ref = TypeRef::from_ast(type_ref);
160 for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
161 self.add_where_predicate_from_bound(bound, type_ref.clone());
162 }
163 }
164 }
165
166 fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) {
167 if bound.has_question_mark() {
168 // FIXME: remove this bound
169 return;
170 }
171 let bound = TypeBound::from_ast(bound);
172 self.where_predicates.push(WherePredicate { type_ref, bound });
173 }
174
175 pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> {
176 self.params.iter().find(|p| &p.name == name)
177 }
178
179 pub fn count_parent_params(&self) -> usize {
180 self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0)
181 }
182
183 pub fn count_params_including_parent(&self) -> usize {
184 let parent_count = self.count_parent_params();
185 parent_count + self.params.len()
186 }
187
188 fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) {
189 if let Some(parent) = &self.parent_params {
190 parent.for_each_param(f);
191 }
192 self.params.iter().for_each(f);
193 }
194
195 pub fn params_including_parent(&self) -> Vec<&GenericParam> {
196 let mut vec = Vec::with_capacity(self.count_params_including_parent());
197 self.for_each_param(&mut |p| vec.push(p));
198 vec
199 }
200}
201
202impl GenericDef {
203 pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver {
204 match self {
205 GenericDef::Function(inner) => inner.resolver(db),
206 GenericDef::Adt(adt) => adt.resolver(db),
207 GenericDef::Trait(inner) => inner.resolver(db),
208 GenericDef::TypeAlias(inner) => inner.resolver(db),
209 GenericDef::ImplBlock(inner) => inner.resolver(db),
210 GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db),
211 GenericDef::Const(inner) => inner.resolver(db),
212 }
213 }
214}
215
216impl From<Container> for GenericDef { 34impl From<Container> for GenericDef {
217 fn from(c: Container) -> Self { 35 fn from(c: Container) -> Self {
218 match c { 36 match c {
@@ -231,6 +49,6 @@ where
231 T: Into<GenericDef> + Copy, 49 T: Into<GenericDef> + Copy,
232{ 50{
233 fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> { 51 fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> {
234 db.generic_params(self.into()) 52 db.generic_params(self.into().into())
235 } 53 }
236} 54}
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 0c2bb8fee..964a3da8c 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -5,8 +5,7 @@ use ra_syntax::ast::{self};
5 5
6use crate::{ 6use crate::{
7 db::{AstDatabase, DefDatabase, HirDatabase}, 7 db::{AstDatabase, DefDatabase, HirDatabase},
8 generics::HasGenericParams, 8 resolve::HasResolver,
9 resolve::Resolver,
10 ty::Ty, 9 ty::Ty,
11 AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, 10 AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef,
12}; 11};
@@ -19,14 +18,6 @@ impl HasSource for ImplBlock {
19} 18}
20 19
21impl ImplBlock { 20impl ImplBlock {
22 pub(crate) fn containing(db: &impl DefDatabase, item: AssocItem) -> Option<ImplBlock> {
23 let module = item.module(db);
24 let crate_def_map = db.crate_def_map(module.id.krate);
25 crate_def_map[module.id.module_id].impls.iter().copied().map(ImplBlock::from).find(|it| {
26 db.impl_data(it.id).items().iter().copied().map(AssocItem::from).any(|it| it == item)
27 })
28 }
29
30 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { 21 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
31 db.impl_data(self.id).target_trait().cloned() 22 db.impl_data(self.id).target_trait().cloned()
32 } 23 }
@@ -59,13 +50,4 @@ impl ImplBlock {
59 pub fn krate(&self, db: &impl DefDatabase) -> Crate { 50 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
60 Crate { crate_id: self.module(db).id.krate } 51 Crate { crate_id: self.module(db).id.krate }
61 } 52 }
62
63 pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
64 let r = self.module(db).resolver(db);
65 // add generic params, if present
66 let p = self.generic_params(db);
67 let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
68 let r = r.push_impl_block_scope(self.clone());
69 r
70 }
71} 53}
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs
index fa2ef8a17..89fd85f59 100644
--- a/crates/ra_hir/src/lang_item.rs
+++ b/crates/ra_hir/src/lang_item.rs
@@ -97,7 +97,7 @@ impl LangItems {
97 // Look for impl targets 97 // Look for impl targets
98 for impl_block in module.impl_blocks(db) { 98 for impl_block in module.impl_blocks(db) {
99 let src = impl_block.source(db); 99 let src = impl_block.source(db);
100 if let Some(lang_item_name) = lang_item_name(&src.ast) { 100 if let Some(lang_item_name) = lang_item_name(&src.value) {
101 self.items 101 self.items
102 .entry(lang_item_name) 102 .entry(lang_item_name)
103 .or_insert_with(|| LangItemTarget::ImplBlock(impl_block)); 103 .or_insert_with(|| LangItemTarget::ImplBlock(impl_block));
@@ -144,7 +144,7 @@ impl LangItems {
144 T: Copy + HasSource<Ast = N>, 144 T: Copy + HasSource<Ast = N>,
145 N: AttrsOwner, 145 N: AttrsOwner,
146 { 146 {
147 let node = item.source(db).ast; 147 let node = item.source(db).value;
148 if let Some(lang_item_name) = lang_item_name(&node) { 148 if let Some(lang_item_name) = lang_item_name(&node) {
149 self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); 149 self.items.entry(lang_item_name).or_insert_with(|| constructor(item));
150 } 150 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index da33c9591..31da74d2f 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -32,8 +32,6 @@ pub mod db;
32pub mod source_binder; 32pub mod source_binder;
33 33
34mod ids; 34mod ids;
35mod adt;
36mod traits;
37mod type_alias; 35mod type_alias;
38mod ty; 36mod ty;
39mod impl_block; 37mod impl_block;
@@ -57,15 +55,14 @@ mod marks;
57use crate::resolve::Resolver; 55use crate::resolve::Resolver;
58 56
59pub use crate::{ 57pub use crate::{
60 adt::VariantDef,
61 code_model::ImplBlock,
62 code_model::{ 58 code_model::{
63 attrs::{AttrDef, Attrs}, 59 attrs::{AttrDef, Attrs},
64 docs::{DocDef, Docs, Documentation}, 60 docs::{DocDef, Docs, Documentation},
65 src::{HasBodySource, HasSource}, 61 src::{HasBodySource, HasSource},
66 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, 62 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum,
67 EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, Local, MacroDef, Module, 63 EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local,
68 ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, 64 MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias,
65 Union, VariantDef,
69 }, 66 },
70 expr::ExprScopes, 67 expr::ExprScopes,
71 from_source::FromSource, 68 from_source::FromSource,
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 79b92180a..eca8e0596 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -14,9 +14,9 @@ use crate::{
14 code_model::Crate, 14 code_model::Crate,
15 db::{DefDatabase, HirDatabase}, 15 db::{DefDatabase, HirDatabase},
16 expr::{ExprScopes, PatId, ScopeId}, 16 expr::{ExprScopes, PatId, ScopeId},
17 generics::GenericParams, 17 generics::{GenericParams, HasGenericParams},
18 Adt, Const, DefWithBody, Enum, EnumVariant, Function, ImplBlock, Local, MacroDef, ModuleDef, 18 Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local,
19 PerNs, Static, Struct, Trait, TypeAlias, 19 MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias,
20}; 20};
21 21
22#[derive(Debug, Clone, Default)] 22#[derive(Debug, Clone, Default)]
@@ -43,7 +43,7 @@ pub(crate) enum Scope {
43 /// All the items and imported names of a module 43 /// All the items and imported names of a module
44 ModuleScope(ModuleItemMap), 44 ModuleScope(ModuleItemMap),
45 /// Brings the generic parameters of an item into scope 45 /// Brings the generic parameters of an item into scope
46 GenericParams(Arc<GenericParams>), 46 GenericParams { def: GenericDef, params: Arc<GenericParams> },
47 /// Brings `Self` in `impl` block into scope 47 /// Brings `Self` in `impl` block into scope
48 ImplBlockScope(ImplBlock), 48 ImplBlockScope(ImplBlock),
49 /// Brings `Self` in enum, struct and union definitions into scope 49 /// Brings `Self` in enum, struct and union definitions into scope
@@ -141,9 +141,9 @@ impl Resolver {
141 for scope in self.scopes.iter().rev() { 141 for scope in self.scopes.iter().rev() {
142 match scope { 142 match scope {
143 Scope::ExprScope(_) => continue, 143 Scope::ExprScope(_) => continue,
144 Scope::GenericParams(_) | Scope::ImplBlockScope(_) if skip_to_mod => continue, 144 Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue,
145 145
146 Scope::GenericParams(params) => { 146 Scope::GenericParams { params, .. } => {
147 if let Some(param) = params.find_by_name(first_name) { 147 if let Some(param) = params.find_by_name(first_name) {
148 let idx = if path.segments.len() == 1 { None } else { Some(1) }; 148 let idx = if path.segments.len() == 1 { None } else { Some(1) };
149 return Some((TypeNs::GenericParam(param.idx), idx)); 149 return Some((TypeNs::GenericParam(param.idx), idx));
@@ -212,7 +212,7 @@ impl Resolver {
212 match scope { 212 match scope {
213 Scope::AdtScope(_) 213 Scope::AdtScope(_)
214 | Scope::ExprScope(_) 214 | Scope::ExprScope(_)
215 | Scope::GenericParams(_) 215 | Scope::GenericParams { .. }
216 | Scope::ImplBlockScope(_) 216 | Scope::ImplBlockScope(_)
217 if skip_to_mod => 217 if skip_to_mod =>
218 { 218 {
@@ -232,13 +232,13 @@ impl Resolver {
232 } 232 }
233 Scope::ExprScope(_) => continue, 233 Scope::ExprScope(_) => continue,
234 234
235 Scope::GenericParams(params) if n_segments > 1 => { 235 Scope::GenericParams { params, .. } if n_segments > 1 => {
236 if let Some(param) = params.find_by_name(first_name) { 236 if let Some(param) = params.find_by_name(first_name) {
237 let ty = TypeNs::GenericParam(param.idx); 237 let ty = TypeNs::GenericParam(param.idx);
238 return Some(ResolveValueResult::Partial(ty, 1)); 238 return Some(ResolveValueResult::Partial(ty, 1));
239 } 239 }
240 } 240 }
241 Scope::GenericParams(_) => continue, 241 Scope::GenericParams { .. } => continue,
242 242
243 Scope::ImplBlockScope(impl_) if n_segments > 1 => { 243 Scope::ImplBlockScope(impl_) if n_segments > 1 => {
244 if first_name == &name::SELF_TYPE { 244 if first_name == &name::SELF_TYPE {
@@ -361,7 +361,7 @@ impl Resolver {
361 self.scopes 361 self.scopes
362 .iter() 362 .iter()
363 .filter_map(|scope| match scope { 363 .filter_map(|scope| match scope {
364 Scope::GenericParams(params) => Some(params), 364 Scope::GenericParams { params, .. } => Some(params),
365 _ => None, 365 _ => None,
366 }) 366 })
367 .flat_map(|params| params.where_predicates.iter()) 367 .flat_map(|params| params.where_predicates.iter())
@@ -369,7 +369,7 @@ impl Resolver {
369 369
370 pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> { 370 pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> {
371 self.scopes.iter().find_map(|scope| match scope { 371 self.scopes.iter().find_map(|scope| match scope {
372 Scope::GenericParams(params) => Some(params.def), 372 Scope::GenericParams { def, .. } => Some(*def),
373 _ => None, 373 _ => None,
374 }) 374 })
375 } 375 }
@@ -381,8 +381,17 @@ impl Resolver {
381 self 381 self
382 } 382 }
383 383
384 pub(crate) fn push_generic_params_scope(self, params: Arc<GenericParams>) -> Resolver { 384 pub(crate) fn push_generic_params_scope(
385 self.push_scope(Scope::GenericParams(params)) 385 self,
386 db: &impl DefDatabase,
387 def: GenericDef,
388 ) -> Resolver {
389 let params = def.generic_params(db);
390 if params.params.is_empty() {
391 self
392 } else {
393 self.push_scope(Scope::GenericParams { def, params })
394 }
386 } 395 }
387 396
388 pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { 397 pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver {
@@ -457,8 +466,8 @@ impl Scope {
457 }); 466 });
458 } 467 }
459 } 468 }
460 Scope::GenericParams(gp) => { 469 Scope::GenericParams { params, .. } => {
461 for param in &gp.params { 470 for param in params.params.iter() {
462 f(param.name.clone(), ScopeDef::GenericParam(param.idx)) 471 f(param.name.clone(), ScopeDef::GenericParam(param.idx))
463 } 472 }
464 } 473 }
@@ -477,3 +486,103 @@ impl Scope {
477 } 486 }
478 } 487 }
479} 488}
489
490pub(crate) trait HasResolver {
491 /// Builds a resolver for type references inside this def.
492 fn resolver(self, db: &impl DefDatabase) -> Resolver;
493}
494
495impl HasResolver for Module {
496 fn resolver(self, db: &impl DefDatabase) -> Resolver {
497 let def_map = db.crate_def_map(self.id.krate);
498 Resolver::default().push_module_scope(def_map, self.id.module_id)
499 }
500}
501
502impl HasResolver for Trait {
503 fn resolver(self, db: &impl DefDatabase) -> Resolver {
504 self.module(db).resolver(db).push_generic_params_scope(db, self.into())
505 }
506}
507
508impl<T: Into<Adt>> HasResolver for T {
509 fn resolver(self, db: &impl DefDatabase) -> Resolver {
510 let def = self.into();
511 def.module(db)
512 .resolver(db)
513 .push_generic_params_scope(db, def.into())
514 .push_scope(Scope::AdtScope(def))
515 }
516}
517
518impl HasResolver for Function {
519 fn resolver(self, db: &impl DefDatabase) -> Resolver {
520 self.container(db)
521 .map(|c| c.resolver(db))
522 .unwrap_or_else(|| self.module(db).resolver(db))
523 .push_generic_params_scope(db, self.into())
524 }
525}
526
527impl HasResolver for DefWithBody {
528 fn resolver(self, db: &impl DefDatabase) -> Resolver {
529 match self {
530 DefWithBody::Const(c) => c.resolver(db),
531 DefWithBody::Function(f) => f.resolver(db),
532 DefWithBody::Static(s) => s.resolver(db),
533 }
534 }
535}
536
537impl HasResolver for Const {
538 fn resolver(self, db: &impl DefDatabase) -> Resolver {
539 self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db))
540 }
541}
542
543impl HasResolver for Static {
544 fn resolver(self, db: &impl DefDatabase) -> Resolver {
545 self.module(db).resolver(db)
546 }
547}
548
549impl HasResolver for TypeAlias {
550 fn resolver(self, db: &impl DefDatabase) -> Resolver {
551 self.container(db)
552 .map(|ib| ib.resolver(db))
553 .unwrap_or_else(|| self.module(db).resolver(db))
554 .push_generic_params_scope(db, self.into())
555 }
556}
557
558impl HasResolver for Container {
559 fn resolver(self, db: &impl DefDatabase) -> Resolver {
560 match self {
561 Container::Trait(trait_) => trait_.resolver(db),
562 Container::ImplBlock(impl_block) => impl_block.resolver(db),
563 }
564 }
565}
566
567impl HasResolver for GenericDef {
568 fn resolver(self, db: &impl DefDatabase) -> crate::Resolver {
569 match self {
570 GenericDef::Function(inner) => inner.resolver(db),
571 GenericDef::Adt(adt) => adt.resolver(db),
572 GenericDef::Trait(inner) => inner.resolver(db),
573 GenericDef::TypeAlias(inner) => inner.resolver(db),
574 GenericDef::ImplBlock(inner) => inner.resolver(db),
575 GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db),
576 GenericDef::Const(inner) => inner.resolver(db),
577 }
578 }
579}
580
581impl HasResolver for ImplBlock {
582 fn resolver(self, db: &impl DefDatabase) -> Resolver {
583 self.module(db)
584 .resolver(db)
585 .push_generic_params_scope(db, self.into())
586 .push_impl_block_scope(self)
587 }
588}
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 5d3196c2a..727310f06 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -23,7 +23,7 @@ use crate::{
23 db::HirDatabase, 23 db::HirDatabase,
24 expr::{self, BodySourceMap, ExprScopes, ScopeId}, 24 expr::{self, BodySourceMap, ExprScopes, ScopeId},
25 ids::LocationCtx, 25 ids::LocationCtx,
26 resolve::{ScopeDef, TypeNs, ValueNs}, 26 resolve::{HasResolver, ScopeDef, TypeNs, ValueNs},
27 ty::method_resolution::{self, implements_trait}, 27 ty::method_resolution::{self, implements_trait},
28 AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, 28 AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody,
29 HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, 29 HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty,
@@ -31,24 +31,24 @@ use crate::{
31 31
32fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 32fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> {
33 match_ast! { 33 match_ast! {
34 match (node.ast) { 34 match (node.value) {
35 ast::Module(it) => { 35 ast::Module(it) => {
36 let src = node.with_ast(it); 36 let src = node.with_value(it);
37 Some(crate::Module::from_declaration(db, src)?.resolver(db)) 37 Some(crate::Module::from_declaration(db, src)?.resolver(db))
38 }, 38 },
39 ast::SourceFile(it) => { 39 ast::SourceFile(it) => {
40 let src = node.with_ast(crate::ModuleSource::SourceFile(it)); 40 let src = node.with_value(crate::ModuleSource::SourceFile(it));
41 Some(crate::Module::from_definition(db, src)?.resolver(db)) 41 Some(crate::Module::from_definition(db, src)?.resolver(db))
42 }, 42 },
43 ast::StructDef(it) => { 43 ast::StructDef(it) => {
44 let src = node.with_ast(it); 44 let src = node.with_value(it);
45 Some(Struct::from_source(db, src)?.resolver(db)) 45 Some(Struct::from_source(db, src)?.resolver(db))
46 }, 46 },
47 ast::EnumDef(it) => { 47 ast::EnumDef(it) => {
48 let src = node.with_ast(it); 48 let src = node.with_value(it);
49 Some(Enum::from_source(db, src)?.resolver(db)) 49 Some(Enum::from_source(db, src)?.resolver(db))
50 }, 50 },
51 _ => match node.ast.kind() { 51 _ => match node.value.kind() {
52 FN_DEF | CONST_DEF | STATIC_DEF => { 52 FN_DEF | CONST_DEF | STATIC_DEF => {
53 Some(def_with_body_from_child_node(db, node)?.resolver(db)) 53 Some(def_with_body_from_child_node(db, node)?.resolver(db))
54 } 54 }
@@ -67,11 +67,11 @@ fn def_with_body_from_child_node(
67 let module = Module::from_definition(db, Source::new(child.file_id, module_source))?; 67 let module = Module::from_definition(db, Source::new(child.file_id, module_source))?;
68 let ctx = LocationCtx::new(db, module.id, child.file_id); 68 let ctx = LocationCtx::new(db, module.id, child.file_id);
69 69
70 child.ast.ancestors().find_map(|node| { 70 child.value.ancestors().find_map(|node| {
71 match_ast! { 71 match_ast! {
72 match node { 72 match node {
73 ast::FnDef(def) => { Some(Function {id: ctx.to_def(&def) }.into()) }, 73 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); },
74 ast::ConstDef(def) => { Some(Const { id: ctx.to_def(&def) }.into()) }, 74 ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); },
75 ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, 75 ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) },
76 _ => { None }, 76 _ => { None },
77 } 77 }
@@ -157,7 +157,7 @@ impl SourceAnalyzer {
157 let scopes = def.expr_scopes(db); 157 let scopes = def.expr_scopes(db);
158 let scope = match offset { 158 let scope = match offset {
159 None => scope_for(&scopes, &source_map, node), 159 None => scope_for(&scopes, &source_map, node),
160 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_ast(offset)), 160 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
161 }; 161 };
162 let resolver = expr::resolver_for_scope(db, def, scope); 162 let resolver = expr::resolver_for_scope(db, def, scope);
163 SourceAnalyzer { 163 SourceAnalyzer {
@@ -171,9 +171,9 @@ impl SourceAnalyzer {
171 } else { 171 } else {
172 SourceAnalyzer { 172 SourceAnalyzer {
173 resolver: node 173 resolver: node
174 .ast 174 .value
175 .ancestors() 175 .ancestors()
176 .find_map(|it| try_get_resolver_for_node(db, node.with_ast(&it))) 176 .find_map(|it| try_get_resolver_for_node(db, node.with_value(&it)))
177 .unwrap_or_default(), 177 .unwrap_or_default(),
178 body_owner: None, 178 body_owner: None,
179 body_source_map: None, 179 body_source_map: None,
@@ -185,12 +185,12 @@ impl SourceAnalyzer {
185 } 185 }
186 186
187 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { 187 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> {
188 let src = Source { file_id: self.file_id, ast: expr }; 188 let src = Source { file_id: self.file_id, value: expr };
189 self.body_source_map.as_ref()?.node_expr(src) 189 self.body_source_map.as_ref()?.node_expr(src)
190 } 190 }
191 191
192 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { 192 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> {
193 let src = Source { file_id: self.file_id, ast: pat }; 193 let src = Source { file_id: self.file_id, value: pat };
194 self.body_source_map.as_ref()?.node_pat(src) 194 self.body_source_map.as_ref()?.node_pat(src)
195 } 195 }
196 196
@@ -302,7 +302,7 @@ impl SourceAnalyzer {
302 let entry = scopes.resolve_name_in_scope(scope, &name)?; 302 let entry = scopes.resolve_name_in_scope(scope, &name)?;
303 Some(ScopeEntryWithSyntax { 303 Some(ScopeEntryWithSyntax {
304 name: entry.name().clone(), 304 name: entry.name().clone(),
305 ptr: source_map.pat_syntax(entry.pat())?.ast, 305 ptr: source_map.pat_syntax(entry.pat())?.value,
306 }) 306 })
307 } 307 }
308 308
@@ -405,9 +405,16 @@ impl SourceAnalyzer {
405 implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) 405 implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait)
406 } 406 }
407 407
408 pub fn expand(&self, db: &impl HirDatabase, macro_call: &ast::MacroCall) -> Option<Expansion> { 408 pub fn expand(
409 let def = self.resolve_macro_call(db, macro_call)?.id; 409 &self,
410 let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(macro_call)); 410 db: &impl HirDatabase,
411 macro_call: Source<&ast::MacroCall>,
412 ) -> Option<Expansion> {
413 let def = self.resolve_macro_call(db, macro_call.value)?.id;
414 let ast_id = AstId::new(
415 macro_call.file_id,
416 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),
417 );
411 let macro_call_loc = MacroCallLoc { def, ast_id }; 418 let macro_call_loc = MacroCallLoc { def, ast_id };
412 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) 419 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) })
413 } 420 }
@@ -421,6 +428,11 @@ impl SourceAnalyzer {
421 pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> { 428 pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> {
422 self.infer.clone().unwrap() 429 self.infer.clone().unwrap()
423 } 430 }
431
432 #[cfg(test)]
433 pub(crate) fn analyzed_declaration(&self) -> Option<DefWithBody> {
434 self.body_owner
435 }
424} 436}
425 437
426fn scope_for( 438fn scope_for(
@@ -428,7 +440,7 @@ fn scope_for(
428 source_map: &BodySourceMap, 440 source_map: &BodySourceMap,
429 node: Source<&SyntaxNode>, 441 node: Source<&SyntaxNode>,
430) -> Option<ScopeId> { 442) -> Option<ScopeId> {
431 node.ast 443 node.value
432 .ancestors() 444 .ancestors()
433 .filter_map(ast::Expr::cast) 445 .filter_map(ast::Expr::cast)
434 .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) 446 .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it)))
@@ -450,18 +462,18 @@ fn scope_for_offset(
450 return None; 462 return None;
451 } 463 }
452 let syntax_node_ptr = 464 let syntax_node_ptr =
453 source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); 465 source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
454 Some((syntax_node_ptr, scope)) 466 Some((syntax_node_ptr, scope))
455 }) 467 })
456 // find containing scope 468 // find containing scope
457 .min_by_key(|(ptr, _scope)| { 469 .min_by_key(|(ptr, _scope)| {
458 ( 470 (
459 !(ptr.range().start() <= offset.ast && offset.ast <= ptr.range().end()), 471 !(ptr.range().start() <= offset.value && offset.value <= ptr.range().end()),
460 ptr.range().len(), 472 ptr.range().len(),
461 ) 473 )
462 }) 474 })
463 .map(|(ptr, scope)| { 475 .map(|(ptr, scope)| {
464 adjust(scopes, source_map, ptr, offset.file_id, offset.ast).unwrap_or(*scope) 476 adjust(scopes, source_map, ptr, offset.file_id, offset.value).unwrap_or(*scope)
465 }) 477 })
466} 478}
467 479
@@ -485,7 +497,7 @@ fn adjust(
485 return None; 497 return None;
486 } 498 }
487 let syntax_node_ptr = 499 let syntax_node_ptr =
488 source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); 500 source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
489 Some((syntax_node_ptr, scope)) 501 Some((syntax_node_ptr, scope))
490 }) 502 })
491 .map(|(ptr, scope)| (ptr.range(), scope)) 503 .map(|(ptr, scope)| (ptr.range(), scope))
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs
deleted file mode 100644
index 1a45dacba..000000000
--- a/crates/ra_hir/src/traits.rs
+++ /dev/null
@@ -1,82 +0,0 @@
1//! HIR for trait definitions.
2
3use std::sync::Arc;
4
5use hir_expand::name::AsName;
6
7use ra_syntax::ast::{self, NameOwner};
8use rustc_hash::FxHashMap;
9
10use crate::{
11 db::{AstDatabase, DefDatabase},
12 ids::LocationCtx,
13 AssocItem, Const, Function, HasSource, Module, Name, Trait, TypeAlias,
14};
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct TraitData {
18 name: Option<Name>,
19 items: Vec<AssocItem>,
20 auto: bool,
21}
22
23impl TraitData {
24 pub(crate) fn trait_data_query(
25 db: &(impl DefDatabase + AstDatabase),
26 tr: Trait,
27 ) -> Arc<TraitData> {
28 let src = tr.source(db);
29 let name = src.ast.name().map(|n| n.as_name());
30 let module = tr.module(db);
31 let ctx = LocationCtx::new(db, module.id, src.file_id);
32 let auto = src.ast.is_auto();
33 let items = if let Some(item_list) = src.ast.item_list() {
34 item_list
35 .impl_items()
36 .map(|item_node| match item_node {
37 ast::ImplItem::FnDef(it) => Function { id: ctx.to_def(&it) }.into(),
38 ast::ImplItem::ConstDef(it) => Const { id: ctx.to_def(&it) }.into(),
39 ast::ImplItem::TypeAliasDef(it) => TypeAlias { id: ctx.to_def(&it) }.into(),
40 })
41 .collect()
42 } else {
43 Vec::new()
44 };
45 Arc::new(TraitData { name, items, auto })
46 }
47
48 pub(crate) fn name(&self) -> &Option<Name> {
49 &self.name
50 }
51
52 pub(crate) fn items(&self) -> &[AssocItem] {
53 &self.items
54 }
55
56 pub(crate) fn is_auto(&self) -> bool {
57 self.auto
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
62pub struct TraitItemsIndex {
63 traits_by_def: FxHashMap<AssocItem, Trait>,
64}
65
66impl TraitItemsIndex {
67 pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex {
68 let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() };
69 for decl in module.declarations(db) {
70 if let crate::ModuleDef::Trait(tr) = decl {
71 for item in tr.trait_data(db).items() {
72 index.traits_by_def.insert(*item, tr);
73 }
74 }
75 }
76 index
77 }
78
79 pub(crate) fn get_parent_trait(&self, item: AssocItem) -> Option<Trait> {
80 self.traits_by_def.get(&item).cloned()
81 }
82}
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index b7f50b714..36ece723f 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -3,8 +3,6 @@
3 3
4mod autoderef; 4mod autoderef;
5pub(crate) mod primitive; 5pub(crate) mod primitive;
6#[cfg(test)]
7mod tests;
8pub(crate) mod traits; 6pub(crate) mod traits;
9pub(crate) mod method_resolution; 7pub(crate) mod method_resolution;
10mod op; 8mod op;
@@ -12,6 +10,9 @@ mod lower;
12mod infer; 10mod infer;
13pub(crate) mod display; 11pub(crate) mod display;
14 12
13#[cfg(test)]
14mod tests;
15
15use std::ops::Deref; 16use std::ops::Deref;
16use std::sync::Arc; 17use std::sync::Arc;
17use std::{fmt, iter, mem}; 18use std::{fmt, iter, mem};
@@ -800,6 +801,10 @@ impl HirDisplay for &Ty {
800 801
801impl HirDisplay for ApplicationTy { 802impl HirDisplay for ApplicationTy {
802 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 803 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
804 if f.should_truncate() {
805 return write!(f, "…");
806 }
807
803 match self.ctor { 808 match self.ctor {
804 TypeCtor::Bool => write!(f, "bool")?, 809 TypeCtor::Bool => write!(f, "bool")?,
805 TypeCtor::Char => write!(f, "char")?, 810 TypeCtor::Char => write!(f, "char")?,
@@ -901,6 +906,10 @@ impl HirDisplay for ApplicationTy {
901 906
902impl HirDisplay for ProjectionTy { 907impl HirDisplay for ProjectionTy {
903 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 908 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
909 if f.should_truncate() {
910 return write!(f, "…");
911 }
912
904 let trait_name = self 913 let trait_name = self
905 .associated_ty 914 .associated_ty
906 .parent_trait(f.db) 915 .parent_trait(f.db)
@@ -919,6 +928,10 @@ impl HirDisplay for ProjectionTy {
919 928
920impl HirDisplay for Ty { 929impl HirDisplay for Ty {
921 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 930 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
931 if f.should_truncate() {
932 return write!(f, "…");
933 }
934
922 match self { 935 match self {
923 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, 936 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
924 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, 937 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
@@ -1001,6 +1014,10 @@ impl HirDisplay for Ty {
1001 1014
1002impl TraitRef { 1015impl TraitRef {
1003 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result { 1016 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result {
1017 if f.should_truncate() {
1018 return write!(f, "…");
1019 }
1020
1004 self.substs[0].hir_fmt(f)?; 1021 self.substs[0].hir_fmt(f)?;
1005 if use_as { 1022 if use_as {
1006 write!(f, " as ")?; 1023 write!(f, " as ")?;
@@ -1031,6 +1048,10 @@ impl HirDisplay for &GenericPredicate {
1031 1048
1032impl HirDisplay for GenericPredicate { 1049impl HirDisplay for GenericPredicate {
1033 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 1050 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1051 if f.should_truncate() {
1052 return write!(f, "…");
1053 }
1054
1034 match self { 1055 match self {
1035 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, 1056 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
1036 GenericPredicate::Projection(projection_pred) => { 1057 GenericPredicate::Projection(projection_pred) => {
diff --git a/crates/ra_hir/src/ty/display.rs b/crates/ra_hir/src/ty/display.rs
index 7910429d7..9bb3ece6c 100644
--- a/crates/ra_hir/src/ty/display.rs
+++ b/crates/ra_hir/src/ty/display.rs
@@ -7,15 +7,30 @@ use crate::db::HirDatabase;
7pub struct HirFormatter<'a, 'b, DB> { 7pub struct HirFormatter<'a, 'b, DB> {
8 pub db: &'a DB, 8 pub db: &'a DB,
9 fmt: &'a mut fmt::Formatter<'b>, 9 fmt: &'a mut fmt::Formatter<'b>,
10 buf: String,
11 curr_size: usize,
12 max_size: Option<usize>,
10} 13}
11 14
12pub trait HirDisplay { 15pub trait HirDisplay {
13 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result; 16 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result;
17
14 fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self> 18 fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self>
15 where 19 where
16 Self: Sized, 20 Self: Sized,
17 { 21 {
18 HirDisplayWrapper(db, self) 22 HirDisplayWrapper(db, self, None)
23 }
24
25 fn display_truncated<'a, DB>(
26 &'a self,
27 db: &'a DB,
28 max_size: Option<usize>,
29 ) -> HirDisplayWrapper<'a, DB, Self>
30 where
31 Self: Sized,
32 {
33 HirDisplayWrapper(db, self, max_size)
19 } 34 }
20} 35}
21 36
@@ -41,11 +56,25 @@ where
41 56
42 /// This allows using the `write!` macro directly with a `HirFormatter`. 57 /// This allows using the `write!` macro directly with a `HirFormatter`.
43 pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { 58 pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
44 fmt::write(self.fmt, args) 59 // We write to a buffer first to track output size
60 self.buf.clear();
61 fmt::write(&mut self.buf, args)?;
62 self.curr_size += self.buf.len();
63
64 // Then we write to the internal formatter from the buffer
65 self.fmt.write_str(&self.buf)
66 }
67
68 pub fn should_truncate(&self) -> bool {
69 if let Some(max_size) = self.max_size {
70 self.curr_size >= max_size
71 } else {
72 false
73 }
45 } 74 }
46} 75}
47 76
48pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T); 77pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>);
49 78
50impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> 79impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T>
51where 80where
@@ -53,6 +82,12 @@ where
53 T: HirDisplay, 82 T: HirDisplay,
54{ 83{
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 84 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 self.1.hir_fmt(&mut HirFormatter { db: self.0, fmt: f }) 85 self.1.hir_fmt(&mut HirFormatter {
86 db: self.0,
87 fmt: f,
88 buf: String::with_capacity(20),
89 curr_size: 0,
90 max_size: self.2,
91 })
57 } 92 }
58} 93}
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index c35378cc4..7f9e81d64 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -37,14 +37,13 @@ use super::{
37 TypeCtor, TypeWalk, Uncertain, 37 TypeCtor, TypeWalk, Uncertain,
38}; 38};
39use crate::{ 39use crate::{
40 adt::VariantDef,
41 code_model::TypeAlias, 40 code_model::TypeAlias,
42 db::HirDatabase, 41 db::HirDatabase,
43 expr::{BindingAnnotation, Body, ExprId, PatId}, 42 expr::{BindingAnnotation, Body, ExprId, PatId},
44 resolve::{Resolver, TypeNs}, 43 resolve::{HasResolver, Resolver, TypeNs},
45 ty::infer::diagnostics::InferenceDiagnostic, 44 ty::infer::diagnostics::InferenceDiagnostic,
46 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, 45 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path,
47 StructField, 46 StructField, VariantDef,
48}; 47};
49 48
50macro_rules! ty_app { 49macro_rules! ty_app {
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index de3c56097..397ee7d5f 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -19,18 +19,17 @@ use super::{
19 TypeWalk, 19 TypeWalk,
20}; 20};
21use crate::{ 21use crate::{
22 adt::VariantDef,
23 db::HirDatabase, 22 db::HirDatabase,
24 generics::HasGenericParams, 23 generics::HasGenericParams,
25 generics::{GenericDef, WherePredicate}, 24 generics::{GenericDef, WherePredicate},
26 resolve::{Resolver, TypeNs}, 25 resolve::{HasResolver, Resolver, TypeNs},
27 ty::{ 26 ty::{
28 primitive::{FloatTy, IntTy, Uncertain}, 27 primitive::{FloatTy, IntTy, Uncertain},
29 Adt, 28 Adt,
30 }, 29 },
31 util::make_mut_slice, 30 util::make_mut_slice,
32 Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, 31 Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait,
33 TypeAlias, Union, 32 TypeAlias, Union, VariantDef,
34}; 33};
35 34
36// FIXME: this is only really used in `type_for_def`, which contains a bunch of 35// FIXME: this is only really used in `type_for_def`, which contains a bunch of
@@ -611,9 +610,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
611 let defaults = generic_params 610 let defaults = generic_params
612 .params_including_parent() 611 .params_including_parent()
613 .into_iter() 612 .into_iter()
614 .map(|p| { 613 .map(|p| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t)))
615 p.default.as_ref().map_or(Ty::Unknown, |path| Ty::from_hir_path(db, &resolver, path))
616 })
617 .collect(); 614 .collect();
618 615
619 Substs(defaults) 616 Substs(defaults)
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index d20aeaacf..f377fca48 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -232,8 +232,8 @@ fn iterate_trait_method_candidates<T>(
232 // trait, but if we find out it doesn't, we'll skip the rest of the 232 // trait, but if we find out it doesn't, we'll skip the rest of the
233 // iteration 233 // iteration
234 let mut known_implemented = false; 234 let mut known_implemented = false;
235 for &item in data.items() { 235 for &item in data.items.iter() {
236 if !is_valid_candidate(db, name, mode, item) { 236 if !is_valid_candidate(db, name, mode, item.into()) {
237 continue; 237 continue;
238 } 238 }
239 if !known_implemented { 239 if !known_implemented {
@@ -243,7 +243,7 @@ fn iterate_trait_method_candidates<T>(
243 } 243 }
244 } 244 }
245 known_implemented = true; 245 known_implemented = true;
246 if let Some(result) = callback(&ty.value, item) { 246 if let Some(result) = callback(&ty.value, item.into()) {
247 return Some(result); 247 return Some(result);
248 } 248 }
249 } 249 }
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index ca1693679..74c12a0a2 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -11,6 +11,7 @@ use ra_syntax::{
11 ast::{self, AstNode}, 11 ast::{self, AstNode},
12 SyntaxKind::*, 12 SyntaxKind::*,
13}; 13};
14use rustc_hash::FxHashSet;
14use test_utils::covers; 15use test_utils::covers;
15 16
16use crate::{ 17use crate::{
@@ -1980,6 +1981,30 @@ fn test() {
1980} 1981}
1981 1982
1982#[test] 1983#[test]
1984fn infer_associated_method_generics_with_default_tuple_param() {
1985 let t = type_at(
1986 r#"
1987//- /main.rs
1988struct Gen<T=()> {
1989 val: T
1990}
1991
1992impl<T> Gen<T> {
1993 pub fn make() -> Gen<T> {
1994 loop { }
1995 }
1996}
1997
1998fn test() {
1999 let a = Gen::make();
2000 a.val<|>;
2001}
2002"#,
2003 );
2004 assert_eq!(t, "()");
2005}
2006
2007#[test]
1983fn infer_associated_method_generics_without_args() { 2008fn infer_associated_method_generics_without_args() {
1984 assert_snapshot!( 2009 assert_snapshot!(
1985 infer(r#" 2010 infer(r#"
@@ -2494,7 +2519,6 @@ fn test() {
2494 [167; 179) 'GLOBAL_CONST': u32 2519 [167; 179) 'GLOBAL_CONST': u32
2495 [189; 191) 'id': u32 2520 [189; 191) 'id': u32
2496 [194; 210) 'Foo::A..._CONST': u32 2521 [194; 210) 'Foo::A..._CONST': u32
2497 [126; 128) '99': u32
2498 "### 2522 "###
2499 ); 2523 );
2500} 2524}
@@ -4694,14 +4718,16 @@ fn infer(content: &str) -> String {
4694 } 4718 }
4695 4719
4696 // sort ranges for consistency 4720 // sort ranges for consistency
4697 types.sort_by_key(|(src_ptr, _)| (src_ptr.ast.range().start(), src_ptr.ast.range().end())); 4721 types.sort_by_key(|(src_ptr, _)| {
4722 (src_ptr.value.range().start(), src_ptr.value.range().end())
4723 });
4698 for (src_ptr, ty) in &types { 4724 for (src_ptr, ty) in &types {
4699 let node = src_ptr.ast.to_node(&src_ptr.file_syntax(&db)); 4725 let node = src_ptr.value.to_node(&src_ptr.file_syntax(&db));
4700 4726
4701 let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) { 4727 let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) {
4702 (self_param.self_kw_token().text_range(), "self".to_string()) 4728 (self_param.self_kw_token().text_range(), "self".to_string())
4703 } else { 4729 } else {
4704 (src_ptr.ast.range(), node.text().to_string().replace("\n", " ")) 4730 (src_ptr.value.range(), node.text().to_string().replace("\n", " "))
4705 }; 4731 };
4706 let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; 4732 let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" };
4707 write!( 4733 write!(
@@ -4716,10 +4742,13 @@ fn infer(content: &str) -> String {
4716 } 4742 }
4717 }; 4743 };
4718 4744
4745 let mut analyzed = FxHashSet::default();
4719 for node in source_file.syntax().descendants() { 4746 for node in source_file.syntax().descendants() {
4720 if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { 4747 if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF {
4721 let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); 4748 let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None);
4722 infer_def(analyzer.inference_result(), analyzer.body_source_map()); 4749 if analyzed.insert(analyzer.analyzed_declaration()) {
4750 infer_def(analyzer.inference_result(), analyzer.body_source_map());
4751 }
4723 } 4752 }
4724 } 4753 }
4725 4754
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs
index 078e6295e..392f244cf 100644
--- a/crates/ra_hir/src/type_alias.rs
+++ b/crates/ra_hir/src/type_alias.rs
@@ -23,7 +23,7 @@ impl TypeAliasData {
23 db: &(impl DefDatabase + AstDatabase), 23 db: &(impl DefDatabase + AstDatabase),
24 typ: TypeAlias, 24 typ: TypeAlias,
25 ) -> Arc<TypeAliasData> { 25 ) -> Arc<TypeAliasData> {
26 let node = typ.source(db).ast; 26 let node = typ.source(db).value;
27 let name = node.name().map_or_else(Name::missing, |n| n.as_name()); 27 let name = node.name().map_or_else(Name::missing, |n| n.as_name());
28 let type_ref = node.type_ref().map(TypeRef::from_ast); 28 let type_ref = node.type_ref().map(TypeRef::from_ast);
29 Arc::new(TypeAliasData { name, type_ref }) 29 Arc::new(TypeAliasData { name, type_ref })