aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model.rs464
-rw-r--r--crates/ra_hir/src/code_model/attrs.rs92
-rw-r--r--crates/ra_hir/src/code_model/docs.rs97
-rw-r--r--crates/ra_hir/src/code_model/src.rs138
-rw-r--r--crates/ra_hir/src/db.rs79
-rw-r--r--crates/ra_hir/src/debug.rs5
-rw-r--r--crates/ra_hir/src/diagnostics.rs3
-rw-r--r--crates/ra_hir/src/expr.rs6
-rw-r--r--crates/ra_hir/src/from_id.rs70
-rw-r--r--crates/ra_hir/src/from_source.rs33
-rw-r--r--crates/ra_hir/src/generics.rs54
-rw-r--r--crates/ra_hir/src/ids.rs45
-rw-r--r--crates/ra_hir/src/impl_block.rs52
-rw-r--r--crates/ra_hir/src/lang_item.rs160
-rw-r--r--crates/ra_hir/src/lib.rs24
-rw-r--r--crates/ra_hir/src/source_binder.rs79
-rw-r--r--crates/ra_hir/src/test_db.rs5
-rw-r--r--crates/ra_hir/src/ty.rs37
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs52
-rw-r--r--crates/ra_hir/src/ty/infer.rs32
-rw-r--r--crates/ra_hir/src/ty/infer/coerce.rs33
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs81
-rw-r--r--crates/ra_hir/src/ty/infer/pat.rs9
-rw-r--r--crates/ra_hir/src/ty/infer/path.rs5
-rw-r--r--crates/ra_hir/src/ty/lower.rs150
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs68
-rw-r--r--crates/ra_hir/src/ty/tests.rs40
-rw-r--r--crates/ra_hir/src/ty/traits.rs11
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs48
-rw-r--r--crates/ra_hir/src/type_alias.rs31
30 files changed, 783 insertions, 1220 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 92860fb59..534f1f8e9 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1,39 +1,33 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3pub(crate) mod src; 3pub(crate) mod src;
4pub(crate) mod docs;
5pub(crate) mod attrs;
6 4
7use std::sync::Arc; 5use std::sync::Arc;
8 6
9use hir_def::{ 7use hir_def::{
10 adt::VariantData, 8 adt::VariantData,
11 body::scope::ExprScopes,
12 builtin_type::BuiltinType, 9 builtin_type::BuiltinType,
13 nameres::per_ns::PerNs, 10 docs::Documentation,
11 per_ns::PerNs,
14 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
15 traits::TraitData, 13 type_ref::TypeRef,
16 type_ref::{Mutability, TypeRef}, 14 AstItemDef, ConstId, ContainerId, EnumId, FunctionId, GenericDefId, HasModule, ImplId,
17 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, 15 LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId,
18 ModuleId, UnionId, 16 StaticId, StructId, TraitId, TypeAliasId, UnionId,
19}; 17};
20use hir_expand::{ 18use hir_expand::{
21 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
22 name::{self, AsName}, 20 name::{self, AsName},
21 AstId, MacroDefId,
23}; 22};
24use ra_db::{CrateId, Edition}; 23use ra_db::{CrateId, Edition, FileId, FilePosition};
25use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 24use ra_syntax::{ast, AstNode, SyntaxNode};
26 25
27use crate::{ 26use crate::{
28 db::{AstDatabase, DefDatabase, HirDatabase}, 27 db::{DefDatabase, HirDatabase},
29 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 28 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
30 generics::{GenericDef, HasGenericParams},
31 ids::{
32 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId,
33 TypeAliasId,
34 },
35 ty::{InferenceResult, Namespace, TraitRef}, 29 ty::{InferenceResult, Namespace, TraitRef},
36 Either, HasSource, ImportId, Name, Source, Ty, 30 Either, Name, Source, Ty,
37}; 31};
38 32
39/// hir::Crate describes a single crate. It's the main interface with which 33/// hir::Crate describes a single crate. It's the main interface with which
@@ -67,7 +61,7 @@ impl Crate {
67 } 61 }
68 62
69 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { 63 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> {
70 let module_id = db.crate_def_map(self.crate_id).root(); 64 let module_id = db.crate_def_map(self.crate_id).root;
71 Some(Module::new(self, module_id)) 65 Some(Module::new(self, module_id))
72 } 66 }
73 67
@@ -81,6 +75,64 @@ impl Crate {
81 } 75 }
82} 76}
83 77
78pub enum ModuleSource {
79 SourceFile(ast::SourceFile),
80 Module(ast::Module),
81}
82
83impl ModuleSource {
84 pub fn new(
85 db: &impl DefDatabase,
86 file_id: Option<FileId>,
87 decl_id: Option<AstId<ast::Module>>,
88 ) -> ModuleSource {
89 match (file_id, decl_id) {
90 (Some(file_id), _) => {
91 let source_file = db.parse(file_id).tree();
92 ModuleSource::SourceFile(source_file)
93 }
94 (None, Some(item_id)) => {
95 let module = item_id.to_node(db);
96 assert!(module.item_list().is_some(), "expected inline module");
97 ModuleSource::Module(module)
98 }
99 (None, None) => panic!(),
100 }
101 }
102
103 // FIXME: this methods do not belong here
104 pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource {
105 let parse = db.parse(position.file_id);
106 match &ra_syntax::algo::find_node_at_offset::<ast::Module>(
107 parse.tree().syntax(),
108 position.offset,
109 ) {
110 Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
111 _ => {
112 let source_file = parse.tree();
113 ModuleSource::SourceFile(source_file)
114 }
115 }
116 }
117
118 pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource {
119 if let Some(m) =
120 child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
121 {
122 ModuleSource::Module(m)
123 } else {
124 let file_id = child.file_id.original_file(db);
125 let source_file = db.parse(file_id).tree();
126 ModuleSource::SourceFile(source_file)
127 }
128 }
129
130 pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource {
131 let source_file = db.parse(file_id).tree();
132 ModuleSource::SourceFile(source_file)
133 }
134}
135
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 136#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85pub struct Module { 137pub struct Module {
86 pub(crate) id: ModuleId, 138 pub(crate) id: ModuleId,
@@ -112,10 +164,10 @@ impl_froms!(
112 BuiltinType 164 BuiltinType
113); 165);
114 166
115pub use hir_def::ModuleSource; 167pub use hir_def::attr::Attrs;
116 168
117impl Module { 169impl Module {
118 pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module { 170 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
119 Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } 171 Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } }
120 } 172 }
121 173
@@ -132,17 +184,6 @@ impl Module {
132 }) 184 })
133 } 185 }
134 186
135 /// Returns the syntax of the last path segment corresponding to this import
136 pub fn import_source(
137 self,
138 db: &impl HirDatabase,
139 import: ImportId,
140 ) -> Either<ast::UseTree, ast::ExternCrateItem> {
141 let src = self.definition_source(db);
142 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
143 source_map.get(&src.value, import)
144 }
145
146 /// Returns the crate this module is part of. 187 /// Returns the crate this module is part of.
147 pub fn krate(self) -> Crate { 188 pub fn krate(self) -> Crate {
148 Crate { crate_id: self.id.krate } 189 Crate { crate_id: self.id.krate }
@@ -153,7 +194,7 @@ impl Module {
153 /// in the module tree of any target in `Cargo.toml`. 194 /// in the module tree of any target in `Cargo.toml`.
154 pub fn crate_root(self, db: &impl DefDatabase) -> Module { 195 pub fn crate_root(self, db: &impl DefDatabase) -> Module {
155 let def_map = db.crate_def_map(self.id.krate); 196 let def_map = db.crate_def_map(self.id.krate);
156 self.with_module_id(def_map.root()) 197 self.with_module_id(def_map.root)
157 } 198 }
158 199
159 /// Finds a child module with the specified name. 200 /// Finds a child module with the specified name.
@@ -192,11 +233,13 @@ impl Module {
192 } 233 }
193 234
194 /// Returns a `ModuleScope`: a set of items, visible in this module. 235 /// Returns a `ModuleScope`: a set of items, visible in this module.
195 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<ImportId>)> { 236 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> {
196 db.crate_def_map(self.id.krate)[self.id.module_id] 237 db.crate_def_map(self.id.krate)[self.id.module_id]
197 .scope 238 .scope
198 .entries() 239 .entries()
199 .map(|(name, res)| (name.clone(), res.def.into(), res.import)) 240 .map(|(name, res)| {
241 (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id }))
242 })
200 .collect() 243 .collect()
201 } 244 }
202 245
@@ -234,11 +277,16 @@ impl Module {
234 def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() 277 def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect()
235 } 278 }
236 279
237 fn with_module_id(self, module_id: CrateModuleId) -> Module { 280 fn with_module_id(self, module_id: LocalModuleId) -> Module {
238 Module::new(self.krate(), module_id) 281 Module::new(self.krate(), module_id)
239 } 282 }
240} 283}
241 284
285pub struct Import {
286 pub(crate) parent: Module,
287 pub(crate) id: LocalImportId,
288}
289
242#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 290#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
243pub struct StructField { 291pub struct StructField {
244 pub(crate) parent: VariantDef, 292 pub(crate) parent: VariantDef,
@@ -253,11 +301,11 @@ pub enum FieldSource {
253 301
254impl StructField { 302impl StructField {
255 pub fn name(&self, db: &impl HirDatabase) -> Name { 303 pub fn name(&self, db: &impl HirDatabase) -> Name {
256 self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() 304 self.parent.variant_data(db).fields()[self.id].name.clone()
257 } 305 }
258 306
259 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 307 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
260 db.type_for_field(*self) 308 db.field_types(self.parent.into())[self.id].clone()
261 } 309 }
262 310
263 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { 311 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef {
@@ -287,8 +335,7 @@ impl Struct {
287 db.struct_data(self.id.into()) 335 db.struct_data(self.id.into())
288 .variant_data 336 .variant_data
289 .fields() 337 .fields()
290 .into_iter() 338 .iter()
291 .flat_map(|it| it.iter())
292 .map(|(id, _)| StructField { parent: self.into(), id }) 339 .map(|(id, _)| StructField { parent: self.into(), id })
293 .collect() 340 .collect()
294 } 341 }
@@ -297,8 +344,7 @@ impl Struct {
297 db.struct_data(self.id.into()) 344 db.struct_data(self.id.into())
298 .variant_data 345 .variant_data
299 .fields() 346 .fields()
300 .into_iter() 347 .iter()
301 .flat_map(|it| it.iter())
302 .find(|(_id, data)| data.name == *name) 348 .find(|(_id, data)| data.name == *name)
303 .map(|(id, _)| StructField { parent: self.into(), id }) 349 .map(|(id, _)| StructField { parent: self.into(), id })
304 } 350 }
@@ -395,8 +441,7 @@ impl EnumVariant {
395 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 441 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
396 self.variant_data(db) 442 self.variant_data(db)
397 .fields() 443 .fields()
398 .into_iter() 444 .iter()
399 .flat_map(|it| it.iter())
400 .map(|(id, _)| StructField { parent: self.into(), id }) 445 .map(|(id, _)| StructField { parent: self.into(), id })
401 .collect() 446 .collect()
402 } 447 }
@@ -404,8 +449,7 @@ impl EnumVariant {
404 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 449 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
405 self.variant_data(db) 450 self.variant_data(db)
406 .fields() 451 .fields()
407 .into_iter() 452 .iter()
408 .flat_map(|it| it.iter())
409 .find(|(_id, data)| data.name == *name) 453 .find(|(_id, data)| data.name == *name)
410 .map(|(id, _)| StructField { parent: self.into(), id }) 454 .map(|(id, _)| StructField { parent: self.into(), id })
411 } 455 }
@@ -461,7 +505,7 @@ impl VariantDef {
461 } 505 }
462 } 506 }
463 507
464 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 508 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
465 match self { 509 match self {
466 VariantDef::Struct(it) => it.field(db, name), 510 VariantDef::Struct(it) => it.field(db, name),
467 VariantDef::EnumVariant(it) => it.field(db, name), 511 VariantDef::EnumVariant(it) => it.field(db, name),
@@ -511,128 +555,11 @@ impl DefWithBody {
511 } 555 }
512} 556}
513 557
514pub trait HasBody: Copy {
515 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>;
516 fn body(self, db: &impl HirDatabase) -> Arc<Body>;
517 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>;
518 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes>;
519}
520
521impl<T> HasBody for T
522where
523 T: Into<DefWithBody> + Copy + HasSource,
524{
525 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
526 db.infer(self.into())
527 }
528
529 fn body(self, db: &impl HirDatabase) -> Arc<Body> {
530 self.into().body(db)
531 }
532
533 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
534 self.into().body_source_map(db)
535 }
536
537 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
538 self.into().expr_scopes(db)
539 }
540}
541
542impl HasBody for DefWithBody {
543 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
544 db.infer(self)
545 }
546
547 fn body(self, db: &impl HirDatabase) -> Arc<Body> {
548 db.body(self.into())
549 }
550
551 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
552 db.body_with_source_map(self.into()).1
553 }
554
555 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
556 db.expr_scopes(self.into())
557 }
558}
559
560#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 558#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
561pub struct Function { 559pub struct Function {
562 pub(crate) id: FunctionId, 560 pub(crate) id: FunctionId,
563} 561}
564 562
565#[derive(Debug, Clone, PartialEq, Eq)]
566pub struct FnData {
567 pub(crate) name: Name,
568 pub(crate) params: Vec<TypeRef>,
569 pub(crate) ret_type: TypeRef,
570 /// True if the first param is `self`. This is relevant to decide whether this
571 /// can be called as a method.
572 pub(crate) has_self_param: bool,
573}
574
575impl FnData {
576 pub(crate) fn fn_data_query(
577 db: &(impl DefDatabase + AstDatabase),
578 func: Function,
579 ) -> Arc<FnData> {
580 let src = func.source(db);
581 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
582 let mut params = Vec::new();
583 let mut has_self_param = false;
584 if let Some(param_list) = src.value.param_list() {
585 if let Some(self_param) = param_list.self_param() {
586 let self_type = if let Some(type_ref) = self_param.ascribed_type() {
587 TypeRef::from_ast(type_ref)
588 } else {
589 let self_type = TypeRef::Path(name::SELF_TYPE.into());
590 match self_param.kind() {
591 ast::SelfParamKind::Owned => self_type,
592 ast::SelfParamKind::Ref => {
593 TypeRef::Reference(Box::new(self_type), Mutability::Shared)
594 }
595 ast::SelfParamKind::MutRef => {
596 TypeRef::Reference(Box::new(self_type), Mutability::Mut)
597 }
598 }
599 };
600 params.push(self_type);
601 has_self_param = true;
602 }
603 for param in param_list.params() {
604 let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
605 params.push(type_ref);
606 }
607 }
608 let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
609 TypeRef::from_ast(type_ref)
610 } else {
611 TypeRef::unit()
612 };
613
614 let sig = FnData { name, params, ret_type, has_self_param };
615 Arc::new(sig)
616 }
617 pub fn name(&self) -> &Name {
618 &self.name
619 }
620
621 pub fn params(&self) -> &[TypeRef] {
622 &self.params
623 }
624
625 pub fn ret_type(&self) -> &TypeRef {
626 &self.ret_type
627 }
628
629 /// True if the first arg is `self`. This is relevant to decide whether this
630 /// can be called as a method.
631 pub fn has_self_param(&self) -> bool {
632 self.has_self_param
633 }
634}
635
636impl Function { 563impl Function {
637 pub fn module(self, db: &impl DefDatabase) -> Module { 564 pub fn module(self, db: &impl DefDatabase) -> Module {
638 self.id.lookup(db).module(db).into() 565 self.id.lookup(db).module(db).into()
@@ -643,10 +570,18 @@ impl Function {
643 } 570 }
644 571
645 pub fn name(self, db: &impl HirDatabase) -> Name { 572 pub fn name(self, db: &impl HirDatabase) -> Name {
646 self.data(db).name.clone() 573 db.function_data(self.id).name.clone()
574 }
575
576 pub fn has_self_param(self, db: &impl HirDatabase) -> bool {
577 db.function_data(self.id).has_self_param
578 }
579
580 pub fn params(self, db: &impl HirDatabase) -> Vec<TypeRef> {
581 db.function_data(self.id).params.clone()
647 } 582 }
648 583
649 pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { 584 pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
650 db.body_with_source_map(self.id.into()).1 585 db.body_with_source_map(self.id.into()).1
651 } 586 }
652 587
@@ -658,10 +593,6 @@ impl Function {
658 db.type_for_def(self.into(), Namespace::Values) 593 db.type_for_def(self.into(), Namespace::Values)
659 } 594 }
660 595
661 pub fn data(self, db: &impl HirDatabase) -> Arc<FnData> {
662 db.fn_data(self)
663 }
664
665 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 596 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
666 db.infer(self.into()) 597 db.infer(self.into())
667 } 598 }
@@ -712,12 +643,8 @@ impl Const {
712 Some(self.module(db).krate()) 643 Some(self.module(db).krate())
713 } 644 }
714 645
715 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> {
716 db.const_data(self)
717 }
718
719 pub fn name(self, db: &impl HirDatabase) -> Option<Name> { 646 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
720 self.data(db).name().cloned() 647 db.const_data(self.id).name.clone()
721 } 648 }
722 649
723 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 650 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
@@ -749,45 +676,6 @@ impl Const {
749 } 676 }
750} 677}
751 678
752#[derive(Debug, Clone, PartialEq, Eq)]
753pub struct ConstData {
754 pub(crate) name: Option<Name>,
755 pub(crate) type_ref: TypeRef,
756}
757
758impl ConstData {
759 pub fn name(&self) -> Option<&Name> {
760 self.name.as_ref()
761 }
762
763 pub fn type_ref(&self) -> &TypeRef {
764 &self.type_ref
765 }
766
767 pub(crate) fn const_data_query(
768 db: &(impl DefDatabase + AstDatabase),
769 konst: Const,
770 ) -> Arc<ConstData> {
771 let node = konst.source(db).value;
772 const_data_for(&node)
773 }
774
775 pub(crate) fn static_data_query(
776 db: &(impl DefDatabase + AstDatabase),
777 konst: Static,
778 ) -> Arc<ConstData> {
779 let node = konst.source(db).value;
780 const_data_for(&node)
781 }
782}
783
784fn const_data_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstData> {
785 let name = node.name().map(|n| n.as_name());
786 let type_ref = TypeRef::from_ast_opt(node.ascribed_type());
787 let sig = ConstData { name, type_ref };
788 Arc::new(sig)
789}
790
791#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 679#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
792pub struct Static { 680pub struct Static {
793 pub(crate) id: StaticId, 681 pub(crate) id: StaticId,
@@ -795,17 +683,13 @@ pub struct Static {
795 683
796impl Static { 684impl Static {
797 pub fn module(self, db: &impl DefDatabase) -> Module { 685 pub fn module(self, db: &impl DefDatabase) -> Module {
798 Module { id: self.id.module(db) } 686 Module { id: self.id.lookup(db).module(db) }
799 } 687 }
800 688
801 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 689 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
802 Some(self.module(db).krate()) 690 Some(self.module(db).krate())
803 } 691 }
804 692
805 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> {
806 db.static_data(self)
807 }
808
809 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 693 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
810 db.infer(self.into()) 694 db.infer(self.into())
811 } 695 }
@@ -822,11 +706,11 @@ impl Trait {
822 } 706 }
823 707
824 pub fn name(self, db: &impl DefDatabase) -> Option<Name> { 708 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
825 self.trait_data(db).name.clone() 709 db.trait_data(self.id).name.clone()
826 } 710 }
827 711
828 pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { 712 pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> {
829 self.trait_data(db).items.iter().map(|it| (*it).into()).collect() 713 db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect()
830 } 714 }
831 715
832 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { 716 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
@@ -835,7 +719,7 @@ impl Trait {
835 // lifetime problems, but since there usually shouldn't be more than a 719 // lifetime problems, but since there usually shouldn't be more than a
836 // few direct traits this should be fine (we could even use some kind of 720 // few direct traits this should be fine (we could even use some kind of
837 // SmallVec if performance is a concern) 721 // SmallVec if performance is a concern)
838 self.generic_params(db) 722 db.generic_params(self.id.into())
839 .where_predicates 723 .where_predicates
840 .iter() 724 .iter()
841 .filter_map(|pred| match &pred.type_ref { 725 .filter_map(|pred| match &pred.type_ref {
@@ -872,7 +756,7 @@ impl Trait {
872 } 756 }
873 757
874 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { 758 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
875 let trait_data = self.trait_data(db); 759 let trait_data = db.trait_data(self.id);
876 let res = 760 let res =
877 trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; 761 trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?;
878 Some(res) 762 Some(res)
@@ -886,16 +770,12 @@ impl Trait {
886 self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) 770 self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name))
887 } 771 }
888 772
889 pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> {
890 db.trait_data(self.id)
891 }
892
893 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { 773 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {
894 TraitRef::for_trait(db, self) 774 TraitRef::for_trait(db, self)
895 } 775 }
896 776
897 pub fn is_auto(self, db: &impl DefDatabase) -> bool { 777 pub fn is_auto(self, db: &impl DefDatabase) -> bool {
898 self.trait_data(db).auto 778 db.trait_data(self.id).auto
899 } 779 }
900} 780}
901 781
@@ -938,7 +818,7 @@ impl TypeAlias {
938 } 818 }
939 819
940 pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { 820 pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> {
941 db.type_alias_data(self).type_ref.clone() 821 db.type_alias_data(self.id).type_ref.clone()
942 } 822 }
943 823
944 pub fn ty(self, db: &impl HirDatabase) -> Ty { 824 pub fn ty(self, db: &impl HirDatabase) -> Ty {
@@ -946,7 +826,7 @@ impl TypeAlias {
946 } 826 }
947 827
948 pub fn name(self, db: &impl DefDatabase) -> Name { 828 pub fn name(self, db: &impl DefDatabase) -> Name {
949 db.type_alias_data(self).name.clone() 829 db.type_alias_data(self.id).name.clone()
950 } 830 }
951} 831}
952 832
@@ -975,16 +855,6 @@ pub enum AssocItem {
975// casting them, and somehow making the constructors private, which would be annoying. 855// casting them, and somehow making the constructors private, which would be annoying.
976impl_froms!(AssocItem: Function, Const, TypeAlias); 856impl_froms!(AssocItem: Function, Const, TypeAlias);
977 857
978impl From<AssocItem> for crate::generics::GenericDef {
979 fn from(item: AssocItem) -> Self {
980 match item {
981 AssocItem::Function(f) => f.into(),
982 AssocItem::Const(c) => c.into(),
983 AssocItem::TypeAlias(t) => t.into(),
984 }
985 }
986}
987
988impl AssocItem { 858impl AssocItem {
989 pub fn module(self, db: &impl DefDatabase) -> Module { 859 pub fn module(self, db: &impl DefDatabase) -> Module {
990 match self { 860 match self {
@@ -1004,6 +874,29 @@ impl AssocItem {
1004 } 874 }
1005} 875}
1006 876
877#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
878pub enum GenericDef {
879 Function(Function),
880 Adt(Adt),
881 Trait(Trait),
882 TypeAlias(TypeAlias),
883 ImplBlock(ImplBlock),
884 // enum variants cannot have generics themselves, but their parent enums
885 // can, and this makes some code easier to write
886 EnumVariant(EnumVariant),
887 // consts can have type parameters from their parents (i.e. associated consts of traits)
888 Const(Const),
889}
890impl_froms!(
891 GenericDef: Function,
892 Adt(Struct, Enum, Union),
893 Trait,
894 TypeAlias,
895 ImplBlock,
896 EnumVariant,
897 Const
898);
899
1007#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 900#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1008pub struct Local { 901pub struct Local {
1009 pub(crate) parent: DefWithBody, 902 pub(crate) parent: DefWithBody,
@@ -1012,7 +905,7 @@ pub struct Local {
1012 905
1013impl Local { 906impl Local {
1014 pub fn name(self, db: &impl HirDatabase) -> Option<Name> { 907 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
1015 let body = self.parent.body(db); 908 let body = db.body(self.parent.into());
1016 match &body[self.pat_id] { 909 match &body[self.pat_id] {
1017 Pat::Bind { name, .. } => Some(name.clone()), 910 Pat::Bind { name, .. } => Some(name.clone()),
1018 _ => None, 911 _ => None,
@@ -1024,7 +917,7 @@ impl Local {
1024 } 917 }
1025 918
1026 pub fn is_mut(self, db: &impl HirDatabase) -> bool { 919 pub fn is_mut(self, db: &impl HirDatabase) -> bool {
1027 let body = self.parent.body(db); 920 let body = db.body(self.parent.into());
1028 match &body[self.pat_id] { 921 match &body[self.pat_id] {
1029 Pat::Bind { mode, .. } => match mode { 922 Pat::Bind { mode, .. } => match mode {
1030 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, 923 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
@@ -1048,7 +941,7 @@ impl Local {
1048 } 941 }
1049 942
1050 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { 943 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> {
1051 let source_map = self.parent.body_source_map(db); 944 let (_body, source_map) = db.body_with_source_map(self.parent.into());
1052 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... 945 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
1053 let root = src.file_syntax(db); 946 let root = src.file_syntax(db);
1054 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) 947 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root)))
@@ -1057,7 +950,7 @@ impl Local {
1057 950
1058#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 951#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1059pub struct GenericParam { 952pub struct GenericParam {
1060 pub(crate) parent: GenericDef, 953 pub(crate) parent: GenericDefId,
1061 pub(crate) idx: u32, 954 pub(crate) idx: u32,
1062} 955}
1063 956
@@ -1066,6 +959,41 @@ pub struct ImplBlock {
1066 pub(crate) id: ImplId, 959 pub(crate) id: ImplId,
1067} 960}
1068 961
962impl ImplBlock {
963 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
964 db.impl_data(self.id).target_trait.clone()
965 }
966
967 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
968 db.impl_data(self.id).target_type.clone()
969 }
970
971 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
972 Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db))
973 }
974
975 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
976 let target_ty = self.target_ty(db);
977 TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty))
978 }
979
980 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
981 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
982 }
983
984 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
985 db.impl_data(self.id).is_negative
986 }
987
988 pub fn module(&self, db: &impl DefDatabase) -> Module {
989 self.id.module(db).into()
990 }
991
992 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
993 Crate { crate_id: self.module(db).id.krate }
994 }
995}
996
1069/// For IDE only 997/// For IDE only
1070pub enum ScopeDef { 998pub enum ScopeDef {
1071 ModuleDef(ModuleDef), 999 ModuleDef(ModuleDef),
@@ -1083,8 +1011,56 @@ impl From<PerNs> for ScopeDef {
1083 .or_else(|| def.take_values()) 1011 .or_else(|| def.take_values())
1084 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) 1012 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
1085 .or_else(|| { 1013 .or_else(|| {
1086 def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) 1014 def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
1087 }) 1015 })
1088 .unwrap_or(ScopeDef::Unknown) 1016 .unwrap_or(ScopeDef::Unknown)
1089 } 1017 }
1090} 1018}
1019
1020#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1021pub enum AttrDef {
1022 Module(Module),
1023 StructField(StructField),
1024 Adt(Adt),
1025 Function(Function),
1026 EnumVariant(EnumVariant),
1027 Static(Static),
1028 Const(Const),
1029 Trait(Trait),
1030 TypeAlias(TypeAlias),
1031 MacroDef(MacroDef),
1032}
1033
1034impl_froms!(
1035 AttrDef: Module,
1036 StructField,
1037 Adt(Struct, Enum, Union),
1038 EnumVariant,
1039 Static,
1040 Const,
1041 Function,
1042 Trait,
1043 TypeAlias,
1044 MacroDef
1045);
1046
1047pub trait HasAttrs {
1048 fn attrs(self, db: &impl DefDatabase) -> Attrs;
1049}
1050
1051impl<T: Into<AttrDef>> HasAttrs for T {
1052 fn attrs(self, db: &impl DefDatabase) -> Attrs {
1053 let def: AttrDef = self.into();
1054 db.attrs(def.into())
1055 }
1056}
1057
1058pub trait Docs {
1059 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>;
1060}
1061impl<T: Into<AttrDef> + Copy> Docs for T {
1062 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
1063 let def: AttrDef = (*self).into();
1064 db.documentation(def.into())
1065 }
1066}
diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs
deleted file mode 100644
index 9e304217c..000000000
--- a/crates/ra_hir/src/code_model/attrs.rs
+++ /dev/null
@@ -1,92 +0,0 @@
1//! FIXME: write short doc here
2
3use crate::{
4 db::{AstDatabase, DefDatabase, HirDatabase},
5 Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static,
6 Struct, StructField, Trait, TypeAlias, Union,
7};
8use hir_def::attr::Attr;
9use hir_expand::hygiene::Hygiene;
10use ra_syntax::ast;
11use std::sync::Arc;
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14pub enum AttrDef {
15 Module(Module),
16 StructField(StructField),
17 Adt(Adt),
18 Function(Function),
19 EnumVariant(EnumVariant),
20 Static(Static),
21 Const(Const),
22 Trait(Trait),
23 TypeAlias(TypeAlias),
24 MacroDef(MacroDef),
25}
26
27impl_froms!(
28 AttrDef: Module,
29 StructField,
30 Adt(Struct, Enum, Union),
31 EnumVariant,
32 Static,
33 Const,
34 Function,
35 Trait,
36 TypeAlias,
37 MacroDef
38);
39
40pub trait Attrs {
41 fn attrs(&self, db: &impl HirDatabase) -> Option<Arc<[Attr]>>;
42}
43
44pub(crate) fn attributes_query(
45 db: &(impl DefDatabase + AstDatabase),
46 def: AttrDef,
47) -> Option<Arc<[Attr]>> {
48 match def {
49 AttrDef::Module(it) => {
50 let src = it.declaration_source(db)?;
51 let hygiene = Hygiene::new(db, src.file_id);
52 Attr::from_attrs_owner(&src.value, &hygiene)
53 }
54 AttrDef::StructField(it) => match it.source(db).value {
55 FieldSource::Named(named) => {
56 let src = it.source(db);
57 let hygiene = Hygiene::new(db, src.file_id);
58 Attr::from_attrs_owner(&named, &hygiene)
59 }
60 FieldSource::Pos(..) => None,
61 },
62 AttrDef::Adt(it) => match it {
63 Adt::Struct(it) => attrs_from_ast(it, db),
64 Adt::Enum(it) => attrs_from_ast(it, db),
65 Adt::Union(it) => attrs_from_ast(it, db),
66 },
67 AttrDef::EnumVariant(it) => attrs_from_ast(it, db),
68 AttrDef::Static(it) => attrs_from_ast(it, db),
69 AttrDef::Const(it) => attrs_from_ast(it, db),
70 AttrDef::Function(it) => attrs_from_ast(it, db),
71 AttrDef::Trait(it) => attrs_from_ast(it, db),
72 AttrDef::TypeAlias(it) => attrs_from_ast(it, db),
73 AttrDef::MacroDef(it) => attrs_from_ast(it, db),
74 }
75}
76
77fn attrs_from_ast<T, D>(node: T, db: &D) -> Option<Arc<[Attr]>>
78where
79 T: HasSource,
80 T::Ast: ast::AttrsOwner,
81 D: DefDatabase + AstDatabase,
82{
83 let src = node.source(db);
84 let hygiene = Hygiene::new(db, src.file_id);
85 Attr::from_attrs_owner(&src.value, &hygiene)
86}
87
88impl<T: Into<AttrDef> + Copy> Attrs for T {
89 fn attrs(&self, db: &impl HirDatabase) -> Option<Arc<[Attr]>> {
90 db.attrs((*self).into())
91 }
92}
diff --git a/crates/ra_hir/src/code_model/docs.rs b/crates/ra_hir/src/code_model/docs.rs
deleted file mode 100644
index e40efef34..000000000
--- a/crates/ra_hir/src/code_model/docs.rs
+++ /dev/null
@@ -1,97 +0,0 @@
1//! FIXME: write short doc here
2
3use std::sync::Arc;
4
5use ra_syntax::ast;
6
7use crate::{
8 db::{AstDatabase, DefDatabase, HirDatabase},
9 Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static,
10 Struct, StructField, Trait, TypeAlias, Union,
11};
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14pub enum DocDef {
15 Module(Module),
16 StructField(StructField),
17 Adt(Adt),
18 EnumVariant(EnumVariant),
19 Static(Static),
20 Const(Const),
21 Function(Function),
22 Trait(Trait),
23 TypeAlias(TypeAlias),
24 MacroDef(MacroDef),
25}
26
27impl_froms!(
28 DocDef: Module,
29 StructField,
30 Adt(Struct, Enum, Union),
31 EnumVariant,
32 Static,
33 Const,
34 Function,
35 Trait,
36 TypeAlias,
37 MacroDef
38);
39
40/// Holds documentation
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct Documentation(Arc<str>);
43
44impl Documentation {
45 fn new(s: &str) -> Documentation {
46 Documentation(s.into())
47 }
48
49 pub fn as_str(&self) -> &str {
50 &*self.0
51 }
52}
53
54impl Into<String> for Documentation {
55 fn into(self) -> String {
56 self.as_str().to_owned()
57 }
58}
59
60pub trait Docs {
61 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>;
62}
63
64pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> {
65 node.doc_comment_text().map(|it| Documentation::new(&it))
66}
67
68pub(crate) fn documentation_query(
69 db: &(impl DefDatabase + AstDatabase),
70 def: DocDef,
71) -> Option<Documentation> {
72 match def {
73 DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.value),
74 DocDef::StructField(it) => match it.source(db).value {
75 FieldSource::Named(named) => docs_from_ast(&named),
76 FieldSource::Pos(..) => None,
77 },
78 DocDef::Adt(it) => match it {
79 Adt::Struct(it) => docs_from_ast(&it.source(db).value),
80 Adt::Enum(it) => docs_from_ast(&it.source(db).value),
81 Adt::Union(it) => docs_from_ast(&it.source(db).value),
82 },
83 DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).value),
84 DocDef::Static(it) => docs_from_ast(&it.source(db).value),
85 DocDef::Const(it) => docs_from_ast(&it.source(db).value),
86 DocDef::Function(it) => docs_from_ast(&it.source(db).value),
87 DocDef::Trait(it) => docs_from_ast(&it.source(db).value),
88 DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).value),
89 DocDef::MacroDef(it) => docs_from_ast(&it.source(db).value),
90 }
91}
92
93impl<T: Into<DocDef> + Copy> Docs for T {
94 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
95 db.documentation((*self).into())
96 }
97}
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index 4aa427de4..a4e317c20 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -1,172 +1,128 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{HasSource as _, Lookup}; 3use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId};
4use ra_syntax::ast::{self, AstNode}; 4use hir_expand::either::Either;
5use ra_syntax::ast;
5 6
6use crate::{ 7use crate::{
7 db::{AstDatabase, DefDatabase, HirDatabase}, 8 db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef,
8 ids::AstItemDef, 9 Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
9 Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module,
10 ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef,
11}; 10};
12 11
13pub use hir_expand::Source; 12pub use hir_expand::Source;
14 13
15pub trait HasSource { 14pub trait HasSource {
16 type Ast; 15 type Ast;
17 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; 16 fn source(self, db: &impl DefDatabase) -> Source<Self::Ast>;
18} 17}
19 18
20/// NB: Module is !HasSource, because it has two source nodes at the same time: 19/// NB: Module is !HasSource, because it has two source nodes at the same time:
21/// definition and declaration. 20/// definition and declaration.
22impl Module { 21impl Module {
23 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. 22 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
24 pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { 23 pub fn definition_source(self, db: &impl DefDatabase) -> Source<ModuleSource> {
25 let def_map = db.crate_def_map(self.id.krate); 24 let def_map = db.crate_def_map(self.id.krate);
26 let decl_id = def_map[self.id.module_id].declaration; 25 let src = def_map[self.id.module_id].definition_source(db);
27 let file_id = def_map[self.id.module_id].definition; 26 src.map(|it| match it {
28 let value = ModuleSource::new(db, file_id, decl_id); 27 Either::A(it) => ModuleSource::SourceFile(it),
29 let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); 28 Either::B(it) => ModuleSource::Module(it),
30 Source { file_id, value } 29 })
31 } 30 }
32 31
33 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. 32 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
34 /// `None` for the crate root. 33 /// `None` for the crate root.
35 pub fn declaration_source( 34 pub fn declaration_source(self, db: &impl DefDatabase) -> Option<Source<ast::Module>> {
36 self,
37 db: &(impl DefDatabase + AstDatabase),
38 ) -> Option<Source<ast::Module>> {
39 let def_map = db.crate_def_map(self.id.krate); 35 let def_map = db.crate_def_map(self.id.krate);
40 let decl = def_map[self.id.module_id].declaration?; 36 def_map[self.id.module_id].declaration_source(db)
41 let value = decl.to_node(db);
42 Some(Source { file_id: decl.file_id(), value })
43 } 37 }
44} 38}
45 39
46impl HasSource for StructField { 40impl HasSource for StructField {
47 type Ast = FieldSource; 41 type Ast = FieldSource;
48 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<FieldSource> { 42 fn source(self, db: &impl DefDatabase) -> Source<FieldSource> {
49 let var_data = self.parent.variant_data(db); 43 let var = VariantId::from(self.parent);
50 let fields = var_data.fields().unwrap(); 44 let src = var.child_source(db);
51 let ss; 45 src.map(|it| match it[self.id].clone() {
52 let es; 46 Either::A(it) => FieldSource::Pos(it),
53 let (file_id, struct_kind) = match self.parent { 47 Either::B(it) => FieldSource::Named(it),
54 VariantDef::Struct(s) => { 48 })
55 ss = s.source(db);
56 (ss.file_id, ss.value.kind())
57 }
58 VariantDef::EnumVariant(e) => {
59 es = e.source(db);
60 (es.file_id, es.value.kind())
61 }
62 };
63
64 let field_sources = match struct_kind {
65 ast::StructKind::Tuple(fl) => fl.fields().map(|it| FieldSource::Pos(it)).collect(),
66 ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(),
67 ast::StructKind::Unit => Vec::new(),
68 };
69 let value = field_sources
70 .into_iter()
71 .zip(fields.iter())
72 .find(|(_syntax, (id, _))| *id == self.id)
73 .unwrap()
74 .0;
75 Source { file_id, value }
76 } 49 }
77} 50}
78impl HasSource for Struct { 51impl HasSource for Struct {
79 type Ast = ast::StructDef; 52 type Ast = ast::StructDef;
80 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StructDef> { 53 fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> {
81 self.id.0.source(db) 54 self.id.0.source(db)
82 } 55 }
83} 56}
84impl HasSource for Union { 57impl HasSource for Union {
85 type Ast = ast::StructDef; 58 type Ast = ast::StructDef;
86 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StructDef> { 59 fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> {
87 self.id.0.source(db) 60 self.id.0.source(db)
88 } 61 }
89} 62}
90impl HasSource for Enum { 63impl HasSource for Enum {
91 type Ast = ast::EnumDef; 64 type Ast = ast::EnumDef;
92 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumDef> { 65 fn source(self, db: &impl DefDatabase) -> Source<ast::EnumDef> {
93 self.id.source(db) 66 self.id.source(db)
94 } 67 }
95} 68}
96impl HasSource for EnumVariant { 69impl HasSource for EnumVariant {
97 type Ast = ast::EnumVariant; 70 type Ast = ast::EnumVariant;
98 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> { 71 fn source(self, db: &impl DefDatabase) -> Source<ast::EnumVariant> {
99 let enum_data = db.enum_data(self.parent.id); 72 self.parent.id.child_source(db).map(|map| map[self.id].clone())
100 let src = self.parent.id.source(db);
101 let value = src
102 .value
103 .variant_list()
104 .into_iter()
105 .flat_map(|it| it.variants())
106 .zip(enum_data.variants.iter())
107 .find(|(_syntax, (id, _))| *id == self.id)
108 .unwrap()
109 .0;
110 Source { file_id: src.file_id, value }
111 } 73 }
112} 74}
113impl HasSource for Function { 75impl HasSource for Function {
114 type Ast = ast::FnDef; 76 type Ast = ast::FnDef;
115 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { 77 fn source(self, db: &impl DefDatabase) -> Source<ast::FnDef> {
116 self.id.lookup(db).source(db) 78 self.id.lookup(db).source(db)
117 } 79 }
118} 80}
119impl HasSource for Const { 81impl HasSource for Const {
120 type Ast = ast::ConstDef; 82 type Ast = ast::ConstDef;
121 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> { 83 fn source(self, db: &impl DefDatabase) -> Source<ast::ConstDef> {
122 self.id.lookup(db).source(db) 84 self.id.lookup(db).source(db)
123 } 85 }
124} 86}
125impl HasSource for Static { 87impl HasSource for Static {
126 type Ast = ast::StaticDef; 88 type Ast = ast::StaticDef;
127 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StaticDef> { 89 fn source(self, db: &impl DefDatabase) -> Source<ast::StaticDef> {
128 self.id.source(db) 90 self.id.lookup(db).source(db)
129 } 91 }
130} 92}
131impl HasSource for Trait { 93impl HasSource for Trait {
132 type Ast = ast::TraitDef; 94 type Ast = ast::TraitDef;
133 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TraitDef> { 95 fn source(self, db: &impl DefDatabase) -> Source<ast::TraitDef> {
134 self.id.source(db) 96 self.id.source(db)
135 } 97 }
136} 98}
137impl HasSource for TypeAlias { 99impl HasSource for TypeAlias {
138 type Ast = ast::TypeAliasDef; 100 type Ast = ast::TypeAliasDef;
139 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { 101 fn source(self, db: &impl DefDatabase) -> Source<ast::TypeAliasDef> {
140 self.id.lookup(db).source(db) 102 self.id.lookup(db).source(db)
141 } 103 }
142} 104}
143impl HasSource for MacroDef { 105impl HasSource for MacroDef {
144 type Ast = ast::MacroCall; 106 type Ast = ast::MacroCall;
145 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::MacroCall> { 107 fn source(self, db: &impl DefDatabase) -> Source<ast::MacroCall> {
146 Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } 108 Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) }
147 } 109 }
148} 110}
149 111impl HasSource for ImplBlock {
150pub trait HasBodySource: HasBody + HasSource 112 type Ast = ast::ImplBlock;
151where 113 fn source(self, db: &impl DefDatabase) -> Source<ast::ImplBlock> {
152 Self::Ast: AstNode, 114 self.id.source(db)
153{
154 fn expr_source(
155 self,
156 db: &impl HirDatabase,
157 expr_id: crate::expr::ExprId,
158 ) -> Option<Source<Either<ast::Expr, ast::RecordField>>> {
159 let source_map = self.body_source_map(db);
160 let source_ptr = source_map.expr_syntax(expr_id)?;
161 let root = source_ptr.file_syntax(db);
162 let source = source_ptr.map(|ast| ast.map(|it| it.to_node(&root), |it| it.to_node(&root)));
163 Some(source)
164 } 115 }
165} 116}
117impl HasSource for Import {
118 type Ast = Either<ast::UseTree, ast::ExternCrateItem>;
166 119
167impl<T> HasBodySource for T 120 /// Returns the syntax of the last path segment corresponding to this import
168where 121 fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> {
169 T: HasBody + HasSource, 122 let src = self.parent.definition_source(db);
170 T::Ast: AstNode, 123 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
171{ 124 let root = db.parse_or_expand(src.file_id).unwrap();
125 let ptr = source_map.get(self.id);
126 src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root)))
127 }
172} 128}
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index a9982a70f..b034d4e44 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -2,80 +2,46 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::attr::Attr; 5use ra_arena::map::ArenaMap;
6use ra_db::salsa; 6use ra_db::salsa;
7use ra_syntax::SmolStr;
8 7
9use crate::{ 8use crate::{
10 debug::HirDebugDatabase,
11 generics::GenericDef,
12 ids,
13 lang_item::{LangItemTarget, LangItems},
14 ty::{ 9 ty::{
15 method_resolution::CrateImplBlocks, 10 method_resolution::CrateImplBlocks,
16 traits::{AssocTyValue, Impl}, 11 traits::{AssocTyValue, Impl},
17 CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, 12 CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef,
18 TypeCtor, 13 TypeCtor,
19 }, 14 },
20 type_alias::TypeAliasData, 15 Crate, DefWithBody, ImplBlock, Trait,
21 Const, ConstData, Crate, DefWithBody, FnData, Function, ImplBlock, Module, Static, StructField,
22 Trait, TypeAlias,
23}; 16};
24 17
25pub use hir_def::db::{ 18pub use hir_def::{
26 BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, 19 db::{
27 EnumDataQuery, ExprScopesQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, 20 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery,
28 InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, 21 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery,
29 TraitDataQuery, 22 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase,
23 InternDatabaseStorage, LangItemQuery, ModuleLangItemsQuery, RawItemsQuery,
24 RawItemsWithSourceMapQuery, StaticDataQuery, StructDataQuery, TraitDataQuery,
25 TypeAliasDataQuery,
26 },
27 GenericDefId, LocalStructFieldId, VariantId,
30}; 28};
31pub use hir_expand::db::{ 29pub use hir_expand::db::{
32 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 30 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
33 ParseMacroQuery, 31 ParseMacroQuery,
34}; 32};
35 33
36// This database uses `AstDatabase` internally,
37#[salsa::query_group(DefDatabaseStorage)]
38#[salsa::requires(AstDatabase)]
39pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
40 #[salsa::invoke(FnData::fn_data_query)]
41 fn fn_data(&self, func: Function) -> Arc<FnData>;
42
43 #[salsa::invoke(TypeAliasData::type_alias_data_query)]
44 fn type_alias_data(&self, typ: TypeAlias) -> Arc<TypeAliasData>;
45
46 #[salsa::invoke(ConstData::const_data_query)]
47 fn const_data(&self, konst: Const) -> Arc<ConstData>;
48
49 #[salsa::invoke(ConstData::static_data_query)]
50 fn static_data(&self, konst: Static) -> Arc<ConstData>;
51
52 #[salsa::invoke(LangItems::module_lang_items_query)]
53 fn module_lang_items(&self, module: Module) -> Option<Arc<LangItems>>;
54
55 #[salsa::invoke(LangItems::crate_lang_items_query)]
56 fn crate_lang_items(&self, krate: Crate) -> Arc<LangItems>;
57
58 #[salsa::invoke(LangItems::lang_item_query)]
59 fn lang_item(&self, start_crate: Crate, item: SmolStr) -> Option<LangItemTarget>;
60
61 #[salsa::invoke(crate::code_model::docs::documentation_query)]
62 fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>;
63
64 #[salsa::invoke(crate::code_model::attrs::attributes_query)]
65 fn attrs(&self, def: crate::AttrDef) -> Option<Arc<[Attr]>>;
66}
67
68#[salsa::query_group(HirDatabaseStorage)] 34#[salsa::query_group(HirDatabaseStorage)]
69#[salsa::requires(salsa::Database)] 35#[salsa::requires(salsa::Database)]
70pub trait HirDatabase: DefDatabase + AstDatabase { 36pub trait HirDatabase: DefDatabase {
71 #[salsa::invoke(crate::ty::infer_query)] 37 #[salsa::invoke(crate::ty::infer_query)]
72 fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; 38 fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>;
73 39
74 #[salsa::invoke(crate::ty::type_for_def)] 40 #[salsa::invoke(crate::ty::type_for_def)]
75 fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; 41 fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty;
76 42
77 #[salsa::invoke(crate::ty::type_for_field)] 43 #[salsa::invoke(crate::ty::field_types_query)]
78 fn type_for_field(&self, field: StructField) -> Ty; 44 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>;
79 45
80 #[salsa::invoke(crate::ty::callable_item_sig)] 46 #[salsa::invoke(crate::ty::callable_item_sig)]
81 fn callable_item_signature(&self, def: CallableDef) -> FnSig; 47 fn callable_item_signature(&self, def: CallableDef) -> FnSig;
@@ -83,15 +49,15 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
83 #[salsa::invoke(crate::ty::generic_predicates_for_param_query)] 49 #[salsa::invoke(crate::ty::generic_predicates_for_param_query)]
84 fn generic_predicates_for_param( 50 fn generic_predicates_for_param(
85 &self, 51 &self,
86 def: GenericDef, 52 def: GenericDefId,
87 param_idx: u32, 53 param_idx: u32,
88 ) -> Arc<[GenericPredicate]>; 54 ) -> Arc<[GenericPredicate]>;
89 55
90 #[salsa::invoke(crate::ty::generic_predicates_query)] 56 #[salsa::invoke(crate::ty::generic_predicates_query)]
91 fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; 57 fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>;
92 58
93 #[salsa::invoke(crate::ty::generic_defaults_query)] 59 #[salsa::invoke(crate::ty::generic_defaults_query)]
94 fn generic_defaults(&self, def: GenericDef) -> Substs; 60 fn generic_defaults(&self, def: GenericDefId) -> Substs;
95 61
96 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] 62 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
97 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; 63 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
@@ -109,11 +75,14 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
109 75
110 // Interned IDs for Chalk integration 76 // Interned IDs for Chalk integration
111 #[salsa::interned] 77 #[salsa::interned]
112 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId; 78 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::ty::TypeCtorId;
113 #[salsa::interned] 79 #[salsa::interned]
114 fn intern_chalk_impl(&self, impl_: Impl) -> ids::GlobalImplId; 80 fn intern_chalk_impl(&self, impl_: Impl) -> crate::ty::traits::GlobalImplId;
115 #[salsa::interned] 81 #[salsa::interned]
116 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> ids::AssocTyValueId; 82 fn intern_assoc_ty_value(
83 &self,
84 assoc_ty_value: AssocTyValue,
85 ) -> crate::ty::traits::AssocTyValueId;
117 86
118 #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] 87 #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)]
119 fn associated_ty_data( 88 fn associated_ty_data(
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs
index 4f3e922c3..7a2810f71 100644
--- a/crates/ra_hir/src/debug.rs
+++ b/crates/ra_hir/src/debug.rs
@@ -1,3 +1,5 @@
1//! XXX: This does not work at the moment.
2//!
1//! printf debugging infrastructure for rust-analyzer. 3//! printf debugging infrastructure for rust-analyzer.
2//! 4//!
3//! When you print a hir type, like a module, using `eprintln!("{:?}", module)`, 5//! When you print a hir type, like a module, using `eprintln!("{:?}", module)`,
@@ -20,9 +22,10 @@
20 22
21use std::fmt; 23use std::fmt;
22 24
25use hir_expand::HirFileId;
23use ra_db::{CrateId, FileId}; 26use ra_db::{CrateId, FileId};
24 27
25use crate::{db::HirDatabase, Crate, HirFileId, Module, Name}; 28use crate::{db::HirDatabase, Crate, Module, Name};
26 29
27impl Crate { 30impl Crate {
28 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { 31 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ {
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs
index 7d1b64858..dafacba70 100644
--- a/crates/ra_hir/src/diagnostics.rs
+++ b/crates/ra_hir/src/diagnostics.rs
@@ -2,9 +2,10 @@
2 2
3use std::any::Any; 3use std::any::Any;
4 4
5use hir_expand::HirFileId;
5use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; 6use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
6 7
7use crate::{db::AstDatabase, HirFileId, Name, Source}; 8use crate::{db::AstDatabase, Name, Source};
8 9
9pub use hir_def::diagnostics::UnresolvedModule; 10pub use hir_def::diagnostics::UnresolvedModule;
10pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; 11pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 6b703d8b4..43fedde7a 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -44,15 +44,15 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
44 pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { 44 pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) {
45 let body = self.func.body(db); 45 let body = self.func.body(db);
46 46
47 for e in body.exprs() { 47 for e in body.exprs.iter() {
48 if let (id, Expr::RecordLit { path, fields, spread }) = e { 48 if let (id, Expr::RecordLit { path, fields, spread }) = e {
49 self.validate_record_literal(id, path, fields, *spread, db); 49 self.validate_record_literal(id, path, fields, *spread, db);
50 } 50 }
51 } 51 }
52 52
53 let body_expr = &body[body.body_expr()]; 53 let body_expr = &body[body.body_expr];
54 if let Expr::Block { statements: _, tail: Some(t) } = body_expr { 54 if let Expr::Block { statements: _, tail: Some(t) } = body_expr {
55 self.validate_results_in_tail_expr(body.body_expr(), *t, db); 55 self.validate_results_in_tail_expr(body.body_expr, *t, db);
56 } 56 }
57 } 57 }
58 58
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs
index a3e9d8525..619f6055e 100644
--- a/crates/ra_hir/src/from_id.rs
+++ b/crates/ra_hir/src/from_id.rs
@@ -4,13 +4,13 @@
4//! are splitting the hir. 4//! are splitting the hir.
5 5
6use hir_def::{ 6use hir_def::{
7 AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, 7 AdtId, AssocItemId, AttrDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
8 ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, 8 GenericDefId, ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId,
9}; 9};
10 10
11use crate::{ 11use crate::{
12 ty::TypableDef, Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, 12 ty::TypableDef, Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function,
13 ModuleDef, Static, TypeAlias, 13 GenericDef, ModuleDef, Static, StructField, TypeAlias, VariantDef,
14}; 14};
15 15
16impl From<ra_db::CrateId> for Crate { 16impl From<ra_db::CrateId> for Crate {
@@ -69,6 +69,12 @@ impl From<EnumVariantId> for EnumVariant {
69 } 69 }
70} 70}
71 71
72impl From<EnumVariant> for EnumVariantId {
73 fn from(def: EnumVariant) -> Self {
74 EnumVariantId { parent: def.parent.id, local_id: def.id }
75 }
76}
77
72impl From<ModuleDefId> for ModuleDef { 78impl From<ModuleDefId> for ModuleDef {
73 fn from(id: ModuleDefId) -> Self { 79 fn from(id: ModuleDefId) -> Self {
74 match id { 80 match id {
@@ -131,20 +137,6 @@ impl From<GenericDef> for GenericDefId {
131 } 137 }
132} 138}
133 139
134impl From<GenericDefId> for GenericDef {
135 fn from(def: GenericDefId) -> Self {
136 match def {
137 GenericDefId::FunctionId(it) => GenericDef::Function(it.into()),
138 GenericDefId::AdtId(it) => GenericDef::Adt(it.into()),
139 GenericDefId::TraitId(it) => GenericDef::Trait(it.into()),
140 GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
141 GenericDefId::ImplId(it) => GenericDef::ImplBlock(it.into()),
142 GenericDefId::EnumVariantId(it) => GenericDef::EnumVariant(it.into()),
143 GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
144 }
145 }
146}
147
148impl From<AdtId> for TypableDef { 140impl From<AdtId> for TypableDef {
149 fn from(id: AdtId) -> Self { 141 fn from(id: AdtId) -> Self {
150 Adt::from(id).into() 142 Adt::from(id).into()
@@ -206,3 +198,45 @@ impl From<Adt> for GenericDefId {
206 } 198 }
207 } 199 }
208} 200}
201
202impl From<VariantDef> for VariantId {
203 fn from(def: VariantDef) -> Self {
204 match def {
205 VariantDef::Struct(it) => VariantId::StructId(it.id),
206 VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()),
207 }
208 }
209}
210
211impl From<StructField> for StructFieldId {
212 fn from(def: StructField) -> Self {
213 StructFieldId { parent: def.parent.into(), local_id: def.id }
214 }
215}
216
217impl From<AttrDef> for AttrDefId {
218 fn from(def: AttrDef) -> Self {
219 match def {
220 AttrDef::Module(it) => AttrDefId::ModuleId(it.id),
221 AttrDef::StructField(it) => AttrDefId::StructFieldId(it.into()),
222 AttrDef::Adt(it) => AttrDefId::AdtId(it.into()),
223 AttrDef::Function(it) => AttrDefId::FunctionId(it.id),
224 AttrDef::EnumVariant(it) => AttrDefId::EnumVariantId(it.into()),
225 AttrDef::Static(it) => AttrDefId::StaticId(it.id),
226 AttrDef::Const(it) => AttrDefId::ConstId(it.id),
227 AttrDef::Trait(it) => AttrDefId::TraitId(it.id),
228 AttrDef::TypeAlias(it) => AttrDefId::TypeAliasId(it.id),
229 AttrDef::MacroDef(it) => AttrDefId::MacroDefId(it.id),
230 }
231 }
232}
233
234impl From<AssocItem> for GenericDefId {
235 fn from(item: AssocItem) -> Self {
236 match item {
237 AssocItem::Function(f) => f.id.into(),
238 AssocItem::Const(c) => c.id.into(),
239 AssocItem::TypeAlias(t) => t.id.into(),
240 }
241 }
242}
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index b86307c58..1e7c22774 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId}; 3use hir_def::{AstItemDef, LocationCtx, 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},
@@ -9,10 +9,9 @@ use ra_syntax::{
9 9
10use crate::{ 10use crate::{
11 db::{AstDatabase, DefDatabase, HirDatabase}, 11 db::{AstDatabase, DefDatabase, HirDatabase},
12 ids::{AstItemDef, LocationCtx}, 12 AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock,
13 AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, 13 Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, StructField, Trait,
14 ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, 14 TypeAlias, Union, VariantDef,
15 StructField, Trait, TypeAlias, Union, VariantDef,
16}; 15};
17 16
18pub trait FromSource: Sized { 17pub trait FromSource: Sized {
@@ -105,10 +104,21 @@ impl FromSource for Const {
105impl FromSource for Static { 104impl FromSource for Static {
106 type Ast = ast::StaticDef; 105 type Ast = ast::StaticDef;
107 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 106 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
108 let id = from_source(db, src)?; 107 let module = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
109 Some(Static { id }) 108 Container::Module(it) => it,
109 Container::Trait(_) | Container::ImplBlock(_) => return None,
110 };
111 module
112 .declarations(db)
113 .into_iter()
114 .filter_map(|it| match it {
115 ModuleDef::Static(it) => Some(it),
116 _ => None,
117 })
118 .find(|it| same_source(&it.source(db), &src))
110 } 119 }
111} 120}
121
112impl FromSource for TypeAlias { 122impl FromSource for TypeAlias {
113 type Ast = ast::TypeAliasDef; 123 type Ast = ast::TypeAliasDef;
114 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 124 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
@@ -190,8 +200,7 @@ impl FromSource for StructField {
190 variant_def 200 variant_def
191 .variant_data(db) 201 .variant_data(db)
192 .fields() 202 .fields()
193 .into_iter() 203 .iter()
194 .flat_map(|it| it.iter())
195 .map(|(id, _)| StructField { parent: variant_def, id }) 204 .map(|(id, _)| StructField { parent: variant_def, id })
196 .find(|f| f.source(db) == src) 205 .find(|f| f.source(db) == src)
197 } 206 }
@@ -211,7 +220,7 @@ impl Local {
211 }; 220 };
212 Some(res) 221 Some(res)
213 })?; 222 })?;
214 let source_map = parent.body_source_map(db); 223 let (_body, source_map) = db.body_with_source_map(parent.into());
215 let src = src.map(ast::Pat::from); 224 let src = src.map(ast::Pat::from);
216 let pat_id = source_map.node_pat(src.as_ref())?; 225 let pat_id = source_map.node_pat(src.as_ref())?;
217 Some(Local { parent, pat_id }) 226 Some(Local { parent, pat_id })
@@ -272,7 +281,9 @@ where
272 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); 281 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
273 let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; 282 let module = Module::from_definition(db, Source::new(src.file_id, module_src))?;
274 let ctx = LocationCtx::new(db, module.id, src.file_id); 283 let ctx = LocationCtx::new(db, module.id, src.file_id);
275 Some(DEF::from_ast(ctx, &src.value)) 284 let items = db.ast_id_map(src.file_id);
285 let item_id = items.ast_id(&src.value);
286 Some(DEF::from_ast_id(ctx, item_id))
276} 287}
277 288
278enum Container { 289enum Container {
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
deleted file mode 100644
index f1bf2ee9d..000000000
--- a/crates/ra_hir/src/generics.rs
+++ /dev/null
@@ -1,54 +0,0 @@
1//! Temp module to wrap hir_def::generics
2use std::sync::Arc;
3
4use crate::{
5 db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait,
6 TypeAlias, Union,
7};
8
9pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate};
10
11#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
12pub enum GenericDef {
13 Function(Function),
14 Adt(Adt),
15 Trait(Trait),
16 TypeAlias(TypeAlias),
17 ImplBlock(ImplBlock),
18 // enum variants cannot have generics themselves, but their parent enums
19 // can, and this makes some code easier to write
20 EnumVariant(EnumVariant),
21 // consts can have type parameters from their parents (i.e. associated consts of traits)
22 Const(Const),
23}
24impl_froms!(
25 GenericDef: Function,
26 Adt(Struct, Enum, Union),
27 Trait,
28 TypeAlias,
29 ImplBlock,
30 EnumVariant,
31 Const
32);
33
34impl From<Container> for GenericDef {
35 fn from(c: Container) -> Self {
36 match c {
37 Container::Trait(trait_) => trait_.into(),
38 Container::ImplBlock(impl_block) => impl_block.into(),
39 }
40 }
41}
42
43pub trait HasGenericParams: Copy {
44 fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>;
45}
46
47impl<T> HasGenericParams for T
48where
49 T: Into<GenericDef> + Copy,
50{
51 fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> {
52 db.generic_params(self.into().into())
53 }
54}
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
deleted file mode 100644
index 2b59365fb..000000000
--- a/crates/ra_hir/src/ids.rs
+++ /dev/null
@@ -1,45 +0,0 @@
1//! hir makes heavy use of ids: integer (u32) handlers to various things. You
2//! can think of id as a pointer (but without a lifetime) or a file descriptor
3//! (but for hir objects).
4//!
5//! This module defines a bunch of ids we are using. The most important ones are
6//! probably `HirFileId` and `DefId`.
7
8use ra_db::salsa;
9
10pub use hir_def::{
11 AstItemDef, ConstId, EnumId, FunctionId, ItemLoc, LocationCtx, StaticId, StructId, TraitId,
12 TypeAliasId,
13};
14pub use hir_expand::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, MacroFileKind};
15
16macro_rules! impl_intern_key {
17 ($name:ident) => {
18 impl salsa::InternKey for $name {
19 fn from_intern_id(v: salsa::InternId) -> Self {
20 $name(v)
21 }
22 fn as_intern_id(&self) -> salsa::InternId {
23 self.0
24 }
25 }
26 };
27}
28
29/// This exists just for Chalk, because Chalk just has a single `StructId` where
30/// we have different kinds of ADTs, primitive types and special type
31/// constructors like tuples and function pointers.
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub struct TypeCtorId(salsa::InternId);
34impl_intern_key!(TypeCtorId);
35
36/// This exists just for Chalk, because our ImplIds are only unique per module.
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
38pub struct GlobalImplId(salsa::InternId);
39impl_intern_key!(GlobalImplId);
40
41/// This exists just for Chalk, because it needs a unique ID for each associated
42/// type value in an impl (even synthetic ones).
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
44pub struct AssocTyValueId(salsa::InternId);
45impl_intern_key!(AssocTyValueId);
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
deleted file mode 100644
index 774fa1d96..000000000
--- a/crates/ra_hir/src/impl_block.rs
+++ /dev/null
@@ -1,52 +0,0 @@
1//! FIXME: write short doc here
2
3use hir_def::{resolver::HasResolver, type_ref::TypeRef, AstItemDef};
4use ra_syntax::ast;
5
6use crate::{
7 db::{AstDatabase, DefDatabase, HirDatabase},
8 ty::Ty,
9 AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef,
10};
11
12impl HasSource for ImplBlock {
13 type Ast = ast::ImplBlock;
14 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ImplBlock> {
15 self.id.source(db)
16 }
17}
18
19impl ImplBlock {
20 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
21 db.impl_data(self.id).target_trait().cloned()
22 }
23
24 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
25 db.impl_data(self.id).target_type().clone()
26 }
27
28 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
29 Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db))
30 }
31
32 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
33 let target_ty = self.target_ty(db);
34 TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty))
35 }
36
37 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
38 db.impl_data(self.id).items().iter().map(|it| (*it).into()).collect()
39 }
40
41 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
42 db.impl_data(self.id).is_negative()
43 }
44
45 pub fn module(&self, db: &impl DefDatabase) -> Module {
46 self.id.module(db).into()
47 }
48
49 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
50 Crate { crate_id: self.module(db).id.krate }
51 }
52}
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs
deleted file mode 100644
index 89fd85f59..000000000
--- a/crates/ra_hir/src/lang_item.rs
+++ /dev/null
@@ -1,160 +0,0 @@
1//! FIXME: write short doc here
2
3use rustc_hash::FxHashMap;
4use std::sync::Arc;
5
6use ra_syntax::{ast::AttrsOwner, SmolStr};
7
8use crate::{
9 db::{AstDatabase, DefDatabase, HirDatabase},
10 Adt, Crate, Enum, Function, HasSource, ImplBlock, Module, ModuleDef, Static, Struct, Trait,
11};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub enum LangItemTarget {
15 Enum(Enum),
16 Function(Function),
17 ImplBlock(ImplBlock),
18 Static(Static),
19 Struct(Struct),
20 Trait(Trait),
21}
22
23impl LangItemTarget {
24 pub(crate) fn krate(&self, db: &impl HirDatabase) -> Option<Crate> {
25 Some(match self {
26 LangItemTarget::Enum(e) => e.module(db).krate(),
27 LangItemTarget::Function(f) => f.module(db).krate(),
28 LangItemTarget::ImplBlock(i) => i.krate(db),
29 LangItemTarget::Static(s) => s.module(db).krate(),
30 LangItemTarget::Struct(s) => s.module(db).krate(),
31 LangItemTarget::Trait(t) => t.module(db).krate(),
32 })
33 }
34}
35
36#[derive(Default, Debug, Clone, PartialEq, Eq)]
37pub struct LangItems {
38 items: FxHashMap<SmolStr, LangItemTarget>,
39}
40
41impl LangItems {
42 pub fn target<'a>(&'a self, item: &str) -> Option<&'a LangItemTarget> {
43 self.items.get(item)
44 }
45
46 /// Salsa query. This will look for lang items in a specific crate.
47 pub(crate) fn crate_lang_items_query(
48 db: &(impl DefDatabase + AstDatabase),
49 krate: Crate,
50 ) -> Arc<LangItems> {
51 let mut lang_items = LangItems::default();
52
53 if let Some(module) = krate.root_module(db) {
54 lang_items.collect_lang_items_recursive(db, module);
55 }
56
57 Arc::new(lang_items)
58 }
59
60 pub(crate) fn module_lang_items_query(
61 db: &(impl DefDatabase + AstDatabase),
62 module: Module,
63 ) -> Option<Arc<LangItems>> {
64 let mut lang_items = LangItems::default();
65 lang_items.collect_lang_items(db, module);
66 if lang_items.items.is_empty() {
67 None
68 } else {
69 Some(Arc::new(lang_items))
70 }
71 }
72
73 /// Salsa query. Look for a lang item, starting from the specified crate and recursively
74 /// traversing its dependencies.
75 pub(crate) fn lang_item_query(
76 db: &impl DefDatabase,
77 start_crate: Crate,
78 item: SmolStr,
79 ) -> Option<LangItemTarget> {
80 let lang_items = db.crate_lang_items(start_crate);
81 let start_crate_target = lang_items.items.get(&item);
82 if let Some(target) = start_crate_target {
83 Some(*target)
84 } else {
85 for dep in start_crate.dependencies(db) {
86 let dep_crate = dep.krate;
87 let dep_target = db.lang_item(dep_crate, item.clone());
88 if dep_target.is_some() {
89 return dep_target;
90 }
91 }
92 None
93 }
94 }
95
96 fn collect_lang_items(&mut self, db: &(impl DefDatabase + AstDatabase), module: Module) {
97 // Look for impl targets
98 for impl_block in module.impl_blocks(db) {
99 let src = impl_block.source(db);
100 if let Some(lang_item_name) = lang_item_name(&src.value) {
101 self.items
102 .entry(lang_item_name)
103 .or_insert_with(|| LangItemTarget::ImplBlock(impl_block));
104 }
105 }
106
107 for def in module.declarations(db) {
108 match def {
109 ModuleDef::Trait(trait_) => {
110 self.collect_lang_item(db, trait_, LangItemTarget::Trait)
111 }
112 ModuleDef::Adt(Adt::Enum(e)) => self.collect_lang_item(db, e, LangItemTarget::Enum),
113 ModuleDef::Adt(Adt::Struct(s)) => {
114 self.collect_lang_item(db, s, LangItemTarget::Struct)
115 }
116 ModuleDef::Function(f) => self.collect_lang_item(db, f, LangItemTarget::Function),
117 ModuleDef::Static(s) => self.collect_lang_item(db, s, LangItemTarget::Static),
118 _ => {}
119 }
120 }
121 }
122
123 fn collect_lang_items_recursive(
124 &mut self,
125 db: &(impl DefDatabase + AstDatabase),
126 module: Module,
127 ) {
128 if let Some(module_lang_items) = db.module_lang_items(module) {
129 self.items.extend(module_lang_items.items.iter().map(|(k, v)| (k.clone(), *v)))
130 }
131
132 // Look for lang items in the children
133 for child in module.children(db) {
134 self.collect_lang_items_recursive(db, child);
135 }
136 }
137
138 fn collect_lang_item<T, N>(
139 &mut self,
140 db: &(impl DefDatabase + AstDatabase),
141 item: T,
142 constructor: fn(T) -> LangItemTarget,
143 ) where
144 T: Copy + HasSource<Ast = N>,
145 N: AttrsOwner,
146 {
147 let node = item.source(db).value;
148 if let Some(lang_item_name) = lang_item_name(&node) {
149 self.items.entry(lang_item_name).or_insert_with(|| constructor(item));
150 }
151 }
152}
153
154fn lang_item_name<T: AttrsOwner>(node: &T) -> Option<SmolStr> {
155 node.attrs()
156 .filter_map(|a| a.as_simple_key_value())
157 .filter(|(key, _)| key == "lang")
158 .map(|(_, val)| val)
159 .nth(0)
160}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 76c96bdcf..843ce6a88 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -31,13 +31,8 @@ pub mod debug;
31pub mod db; 31pub mod db;
32pub mod source_binder; 32pub mod source_binder;
33 33
34mod ids;
35mod type_alias;
36mod ty; 34mod ty;
37mod impl_block;
38mod expr; 35mod expr;
39mod lang_item;
40pub mod generics;
41pub mod diagnostics; 36pub mod diagnostics;
42mod util; 37mod util;
43 38
@@ -53,18 +48,13 @@ mod marks;
53 48
54pub use crate::{ 49pub use crate::{
55 code_model::{ 50 code_model::{
56 attrs::{AttrDef, Attrs}, 51 src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency,
57 docs::{DocDef, Docs, Documentation}, 52 DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam,
58 src::{HasBodySource, HasSource}, 53 HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef,
59 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, 54 Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef,
60 EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local,
61 MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait,
62 TypeAlias, Union, VariantDef,
63 }, 55 },
64 expr::ExprScopes, 56 expr::ExprScopes,
65 from_source::FromSource, 57 from_source::FromSource,
66 generics::GenericDef,
67 ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile},
68 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, 58 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
69 ty::{ 59 ty::{
70 display::HirDisplay, 60 display::HirDisplay,
@@ -75,8 +65,10 @@ pub use crate::{
75 65
76pub use hir_def::{ 66pub use hir_def::{
77 builtin_type::BuiltinType, 67 builtin_type::BuiltinType,
78 nameres::{per_ns::PerNs, raw::ImportId}, 68 docs::Documentation,
79 path::{Path, PathKind}, 69 path::{Path, PathKind},
80 type_ref::Mutability, 70 type_ref::Mutability,
81}; 71};
82pub use hir_expand::{either::Either, name::Name, Source}; 72pub use hir_expand::{
73 either::Either, name::Name, HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Source,
74};
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index c42ceabdf..cbfeca3ab 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -13,7 +13,9 @@ use hir_def::{
13 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, 13 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
14 DefWithBodyId, 14 DefWithBodyId,
15}; 15};
16use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; 16use hir_expand::{
17 name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source,
18};
17use ra_syntax::{ 19use ra_syntax::{
18 ast::{self, AstNode}, 20 ast::{self, AstNode},
19 match_ast, AstPtr, 21 match_ast, AstPtr,
@@ -24,11 +26,12 @@ use ra_syntax::{
24use crate::{ 26use crate::{
25 db::HirDatabase, 27 db::HirDatabase,
26 expr::{BodySourceMap, ExprScopes, ScopeId}, 28 expr::{BodySourceMap, ExprScopes, ScopeId},
27 ids::LocationCtx, 29 ty::{
28 ty::method_resolution::{self, implements_trait}, 30 method_resolution::{self, implements_trait},
31 TraitEnvironment,
32 },
29 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, 33 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function,
30 GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, ScopeDef, Static, 34 GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias,
31 Struct, Trait, Ty, TypeAlias,
32}; 35};
33 36
34fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 37fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> {
@@ -67,16 +70,12 @@ fn def_with_body_from_child_node(
67 db: &impl HirDatabase, 70 db: &impl HirDatabase,
68 child: Source<&SyntaxNode>, 71 child: Source<&SyntaxNode>,
69) -> Option<DefWithBody> { 72) -> Option<DefWithBody> {
70 let module_source = crate::ModuleSource::from_child_node(db, child);
71 let module = Module::from_definition(db, Source::new(child.file_id, module_source))?;
72 let ctx = LocationCtx::new(db, module.id, child.file_id);
73
74 child.value.ancestors().find_map(|node| { 73 child.value.ancestors().find_map(|node| {
75 match_ast! { 74 match_ast! {
76 match node { 75 match node {
77 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, 76 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); },
78 ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, 77 ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); },
79 ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, 78 ast::StaticDef(def) => { return Static::from_source(db, child.with_value(def)).map(DefWithBody::from); },
80 _ => { None }, 79 _ => { None },
81 } 80 }
82 } 81 }
@@ -131,6 +130,7 @@ pub struct ReferenceDescriptor {
131} 130}
132 131
133pub struct Expansion { 132pub struct Expansion {
133 macro_file_kind: MacroFileKind,
134 macro_call_id: MacroCallId, 134 macro_call_id: MacroCallId,
135} 135}
136 136
@@ -145,7 +145,7 @@ impl Expansion {
145 } 145 }
146 146
147 pub fn file_id(&self) -> HirFileId { 147 pub fn file_id(&self) -> HirFileId {
148 self.macro_call_id.as_file(MacroFileKind::Items) 148 self.macro_call_id.as_file(self.macro_file_kind)
149 } 149 }
150} 150}
151 151
@@ -157,8 +157,8 @@ impl SourceAnalyzer {
157 ) -> SourceAnalyzer { 157 ) -> SourceAnalyzer {
158 let def_with_body = def_with_body_from_child_node(db, node); 158 let def_with_body = def_with_body_from_child_node(db, node);
159 if let Some(def) = def_with_body { 159 if let Some(def) = def_with_body {
160 let source_map = def.body_source_map(db); 160 let (_body, source_map) = db.body_with_source_map(def.into());
161 let scopes = def.expr_scopes(db); 161 let scopes = db.expr_scopes(def.into());
162 let scope = match offset { 162 let scope = match offset {
163 None => scope_for(&scopes, &source_map, node), 163 None => scope_for(&scopes, &source_map, node),
164 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), 164 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
@@ -168,7 +168,7 @@ impl SourceAnalyzer {
168 resolver, 168 resolver,
169 body_owner: Some(def), 169 body_owner: Some(def),
170 body_source_map: Some(source_map), 170 body_source_map: Some(source_map),
171 infer: Some(def.infer(db)), 171 infer: Some(db.infer(def)),
172 scopes: Some(scopes), 172 scopes: Some(scopes),
173 file_id: node.file_id, 173 file_id: node.file_id,
174 } 174 }
@@ -218,6 +218,11 @@ impl SourceAnalyzer {
218 self.infer.as_ref()?.field_resolution(expr_id) 218 self.infer.as_ref()?.field_resolution(expr_id)
219 } 219 }
220 220
221 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> {
222 let expr_id = self.expr_id(&field.expr()?)?;
223 self.infer.as_ref()?.record_field_resolution(expr_id)
224 }
225
221 pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { 226 pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> {
222 let expr_id = self.expr_id(&record_lit.clone().into())?; 227 let expr_id = self.expr_id(&record_lit.clone().into())?;
223 self.infer.as_ref()?.variant_resolution_for_expr(expr_id) 228 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
@@ -246,7 +251,7 @@ impl SourceAnalyzer {
246 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { 251 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty {
247 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), 252 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
248 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { 253 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam {
249 parent: self.resolver.generic_def().unwrap().into(), 254 parent: self.resolver.generic_def().unwrap(),
250 idx, 255 idx,
251 }), 256 }),
252 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { 257 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
@@ -321,7 +326,7 @@ impl SourceAnalyzer {
321 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), 326 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
322 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), 327 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
323 resolver::ScopeDef::GenericParam(idx) => { 328 resolver::ScopeDef::GenericParam(idx) => {
324 let parent = self.resolver.generic_def().unwrap().into(); 329 let parent = self.resolver.generic_def().unwrap();
325 ScopeDef::GenericParam(GenericParam { parent, idx }) 330 ScopeDef::GenericParam(GenericParam { parent, idx })
326 } 331 }
327 resolver::ScopeDef::Local(pat_id) => { 332 resolver::ScopeDef::Local(pat_id) => {
@@ -406,7 +411,10 @@ impl SourceAnalyzer {
406 // There should be no inference vars in types passed here 411 // There should be no inference vars in types passed here
407 // FIXME check that? 412 // FIXME check that?
408 let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; 413 let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
409 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) 414 let krate = self.resolver.krate();
415 let environment = TraitEnvironment::lower(db, &self.resolver);
416 let ty = crate::ty::InEnvironment { value: canonical, environment };
417 crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value)
410 } 418 }
411 419
412 /// Checks that particular type `ty` implements `std::future::Future`. 420 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -439,7 +447,10 @@ impl SourceAnalyzer {
439 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), 447 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),
440 ); 448 );
441 let macro_call_loc = MacroCallLoc { def, ast_id }; 449 let macro_call_loc = MacroCallLoc { def, ast_id };
442 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) 450 Some(Expansion {
451 macro_call_id: db.intern_macro(macro_call_loc),
452 macro_file_kind: to_macro_file_kind(macro_call.value),
453 })
443 } 454 }
444 455
445 #[cfg(test)] 456 #[cfg(test)]
@@ -538,3 +549,35 @@ fn adjust(
538 }) 549 })
539 .map(|(_ptr, scope)| *scope) 550 .map(|(_ptr, scope)| *scope)
540} 551}
552
553/// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to.
554/// FIXME: Not completed
555fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind {
556 let syn = macro_call.syntax();
557 let parent = match syn.parent() {
558 Some(it) => it,
559 None => {
560 // FIXME:
561 // If it is root, which means the parent HirFile
562 // MacroKindFile must be non-items
563 // return expr now.
564 return MacroFileKind::Expr;
565 }
566 };
567
568 match parent.kind() {
569 MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items,
570 LET_STMT => {
571 // FIXME: Handle Pattern
572 MacroFileKind::Expr
573 }
574 EXPR_STMT => MacroFileKind::Statements,
575 BLOCK => MacroFileKind::Statements,
576 ARG_LIST => MacroFileKind::Expr,
577 TRY_EXPR => MacroFileKind::Expr,
578 _ => {
579 // Unknown , Just guess it is `Items`
580 MacroFileKind::Items
581 }
582 }
583}
diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir/src/test_db.rs
index 1caa2e875..efee2f658 100644
--- a/crates/ra_hir/src/test_db.rs
+++ b/crates/ra_hir/src/test_db.rs
@@ -2,7 +2,7 @@
2 2
3use std::{panic, sync::Arc}; 3use std::{panic, sync::Arc};
4 4
5use hir_def::{db::DefDatabase2, ModuleId}; 5use hir_def::{db::DefDatabase, ModuleId};
6use hir_expand::diagnostics::DiagnosticSink; 6use hir_expand::diagnostics::DiagnosticSink;
7use parking_lot::Mutex; 7use parking_lot::Mutex;
8use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase}; 8use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase};
@@ -15,7 +15,6 @@ use crate::{db, debug::HirDebugHelper};
15 db::InternDatabaseStorage, 15 db::InternDatabaseStorage,
16 db::AstDatabaseStorage, 16 db::AstDatabaseStorage,
17 db::DefDatabaseStorage, 17 db::DefDatabaseStorage,
18 db::DefDatabase2Storage,
19 db::HirDatabaseStorage 18 db::HirDatabaseStorage
20)] 19)]
21#[derive(Debug, Default)] 20#[derive(Debug, Default)]
@@ -81,7 +80,7 @@ impl TestDB {
81 let crate_graph = self.crate_graph(); 80 let crate_graph = self.crate_graph();
82 for krate in crate_graph.iter().next() { 81 for krate in crate_graph.iter().next() {
83 let crate_def_map = self.crate_def_map(krate); 82 let crate_def_map = self.crate_def_map(krate);
84 for module_id in crate_def_map.modules() { 83 for (module_id, _) in crate_def_map.modules.iter() {
85 let module_id = ModuleId { krate, module_id }; 84 let module_id = ModuleId { krate, module_id };
86 let module = crate::Module::from(module_id); 85 let module = crate::Module::from(module_id);
87 module.diagnostics( 86 module.diagnostics(
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 36ece723f..1e05ac3f2 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -17,12 +17,12 @@ use std::ops::Deref;
17use std::sync::Arc; 17use std::sync::Arc;
18use std::{fmt, iter, mem}; 18use std::{fmt, iter, mem};
19 19
20use hir_def::{generics::GenericParams, AdtId, GenericDefId};
21use ra_db::{impl_intern_key, salsa};
22
20use crate::{ 23use crate::{
21 db::HirDatabase, 24 db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, IntTy,
22 expr::ExprId, 25 Mutability, Name, Trait, TypeAlias, Uncertain,
23 generics::{GenericParams, HasGenericParams},
24 util::make_mut_slice,
25 Adt, Crate, DefWithBody, FloatTy, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain,
26}; 26};
27use display::{HirDisplay, HirFormatter}; 27use display::{HirDisplay, HirFormatter};
28 28
@@ -30,8 +30,9 @@ pub(crate) use autoderef::autoderef;
30pub(crate) use infer::{infer_query, InferTy, InferenceResult}; 30pub(crate) use infer::{infer_query, InferTy, InferenceResult};
31pub use lower::CallableDef; 31pub use lower::CallableDef;
32pub(crate) use lower::{ 32pub(crate) use lower::{
33 callable_item_sig, generic_defaults_query, generic_predicates_for_param_query, 33 callable_item_sig, field_types_query, generic_defaults_query,
34 generic_predicates_query, type_for_def, type_for_field, Namespace, TypableDef, 34 generic_predicates_for_param_query, generic_predicates_query, type_for_def, Namespace,
35 TypableDef,
35}; 36};
36pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 37pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
37 38
@@ -115,6 +116,13 @@ pub enum TypeCtor {
115 Closure { def: DefWithBody, expr: ExprId }, 116 Closure { def: DefWithBody, expr: ExprId },
116} 117}
117 118
119/// This exists just for Chalk, because Chalk just has a single `StructId` where
120/// we have different kinds of ADTs, primitive types and special type
121/// constructors like tuples and function pointers.
122#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
123pub struct TypeCtorId(salsa::InternId);
124impl_intern_key!(TypeCtorId);
125
118impl TypeCtor { 126impl TypeCtor {
119 pub fn num_ty_params(self, db: &impl HirDatabase) -> usize { 127 pub fn num_ty_params(self, db: &impl HirDatabase) -> usize {
120 match self { 128 match self {
@@ -131,15 +139,15 @@ impl TypeCtor {
131 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure 139 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure
132 => 1, 140 => 1,
133 TypeCtor::Adt(adt) => { 141 TypeCtor::Adt(adt) => {
134 let generic_params = adt.generic_params(db); 142 let generic_params = db.generic_params(AdtId::from(adt).into());
135 generic_params.count_params_including_parent() 143 generic_params.count_params_including_parent()
136 } 144 }
137 TypeCtor::FnDef(callable) => { 145 TypeCtor::FnDef(callable) => {
138 let generic_params = callable.generic_params(db); 146 let generic_params = db.generic_params(callable.into());
139 generic_params.count_params_including_parent() 147 generic_params.count_params_including_parent()
140 } 148 }
141 TypeCtor::AssociatedType(type_alias) => { 149 TypeCtor::AssociatedType(type_alias) => {
142 let generic_params = type_alias.generic_params(db); 150 let generic_params = db.generic_params(type_alias.id.into());
143 generic_params.count_params_including_parent() 151 generic_params.count_params_including_parent()
144 } 152 }
145 TypeCtor::FnPtr { num_args } => num_args as usize + 1, 153 TypeCtor::FnPtr { num_args } => num_args as usize + 1,
@@ -168,7 +176,7 @@ impl TypeCtor {
168 } 176 }
169 } 177 }
170 178
171 pub fn as_generic_def(self) -> Option<crate::generics::GenericDef> { 179 pub fn as_generic_def(self) -> Option<GenericDefId> {
172 match self { 180 match self {
173 TypeCtor::Bool 181 TypeCtor::Bool
174 | TypeCtor::Char 182 | TypeCtor::Char
@@ -185,7 +193,7 @@ impl TypeCtor {
185 | TypeCtor::Closure { .. } => None, 193 | TypeCtor::Closure { .. } => None,
186 TypeCtor::Adt(adt) => Some(adt.into()), 194 TypeCtor::Adt(adt) => Some(adt.into()),
187 TypeCtor::FnDef(callable) => Some(callable.into()), 195 TypeCtor::FnDef(callable) => Some(callable.into()),
188 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), 196 TypeCtor::AssociatedType(type_alias) => Some(type_alias.id.into()),
189 } 197 }
190 } 198 }
191} 199}
@@ -348,8 +356,9 @@ impl Substs {
348 ) 356 )
349 } 357 }
350 358
351 pub fn build_for_def(db: &impl HirDatabase, def: impl HasGenericParams) -> SubstsBuilder { 359 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
352 let params = def.generic_params(db); 360 let def = def.into();
361 let params = db.generic_params(def);
353 let param_count = params.count_params_including_parent(); 362 let param_count = params.count_params_including_parent();
354 Substs::builder(param_count) 363 Substs::builder(param_count)
355 } 364 }
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 5d8518041..44547197c 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -5,48 +5,56 @@
5 5
6use std::iter::successors; 6use std::iter::successors;
7 7
8use hir_def::resolver::Resolver; 8use hir_def::lang_item::LangItemTarget;
9use hir_expand::name; 9use hir_expand::name;
10use log::{info, warn}; 10use log::{info, warn};
11use ra_db::CrateId;
11 12
12use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; 13use crate::{db::HirDatabase, Trait};
13use crate::{db::HirDatabase, generics::HasGenericParams}; 14
15use super::{
16 traits::{InEnvironment, Solution},
17 Canonical, Substs, Ty, TypeWalk,
18};
14 19
15const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
16 21
17pub(crate) fn autoderef<'a>( 22pub(crate) fn autoderef<'a>(
18 db: &'a impl HirDatabase, 23 db: &'a impl HirDatabase,
19 resolver: &'a Resolver, 24 krate: Option<CrateId>,
20 ty: Canonical<Ty>, 25 ty: InEnvironment<Canonical<Ty>>,
21) -> impl Iterator<Item = Canonical<Ty>> + 'a { 26) -> impl Iterator<Item = Canonical<Ty>> + 'a {
22 successors(Some(ty), move |ty| deref(db, resolver, ty)).take(AUTODEREF_RECURSION_LIMIT) 27 let InEnvironment { value: ty, environment } = ty;
28 successors(Some(ty), move |ty| {
29 deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() })
30 })
31 .take(AUTODEREF_RECURSION_LIMIT)
23} 32}
24 33
25pub(crate) fn deref( 34pub(crate) fn deref(
26 db: &impl HirDatabase, 35 db: &impl HirDatabase,
27 resolver: &Resolver, 36 krate: CrateId,
28 ty: &Canonical<Ty>, 37 ty: InEnvironment<&Canonical<Ty>>,
29) -> Option<Canonical<Ty>> { 38) -> Option<Canonical<Ty>> {
30 if let Some(derefed) = ty.value.builtin_deref() { 39 if let Some(derefed) = ty.value.value.builtin_deref() {
31 Some(Canonical { value: derefed, num_vars: ty.num_vars }) 40 Some(Canonical { value: derefed, num_vars: ty.value.num_vars })
32 } else { 41 } else {
33 deref_by_trait(db, resolver, ty) 42 deref_by_trait(db, krate, ty)
34 } 43 }
35} 44}
36 45
37fn deref_by_trait( 46fn deref_by_trait(
38 db: &impl HirDatabase, 47 db: &impl HirDatabase,
39 resolver: &Resolver, 48 krate: CrateId,
40 ty: &Canonical<Ty>, 49 ty: InEnvironment<&Canonical<Ty>>,
41) -> Option<Canonical<Ty>> { 50) -> Option<Canonical<Ty>> {
42 let krate = resolver.krate()?;
43 let deref_trait = match db.lang_item(krate.into(), "deref".into())? { 51 let deref_trait = match db.lang_item(krate.into(), "deref".into())? {
44 crate::lang_item::LangItemTarget::Trait(t) => t, 52 LangItemTarget::TraitId(t) => Trait::from(t),
45 _ => return None, 53 _ => return None,
46 }; 54 };
47 let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; 55 let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?;
48 56
49 let generic_params = target.generic_params(db); 57 let generic_params = db.generic_params(target.id.into());
50 if generic_params.count_params_including_parent() != 1 { 58 if generic_params.count_params_including_parent() != 1 {
51 // the Target type + Deref trait should only have one generic parameter, 59 // the Target type + Deref trait should only have one generic parameter,
52 // namely Deref's Self type 60 // namely Deref's Self type
@@ -55,10 +63,8 @@ fn deref_by_trait(
55 63
56 // FIXME make the Canonical handling nicer 64 // FIXME make the Canonical handling nicer
57 65
58 let env = super::lower::trait_env(db, resolver);
59
60 let parameters = Substs::build_for_generics(&generic_params) 66 let parameters = Substs::build_for_generics(&generic_params)
61 .push(ty.value.clone().shift_bound_vars(1)) 67 .push(ty.value.value.clone().shift_bound_vars(1))
62 .build(); 68 .build();
63 69
64 let projection = super::traits::ProjectionPredicate { 70 let projection = super::traits::ProjectionPredicate {
@@ -68,9 +74,9 @@ fn deref_by_trait(
68 74
69 let obligation = super::Obligation::Projection(projection); 75 let obligation = super::Obligation::Projection(projection);
70 76
71 let in_env = super::traits::InEnvironment { value: obligation, environment: env }; 77 let in_env = InEnvironment { value: obligation, environment: ty.environment };
72 78
73 let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; 79 let canonical = super::Canonical { num_vars: 1 + ty.value.num_vars, value: in_env };
74 80
75 let solution = db.trait_solve(krate.into(), canonical)?; 81 let solution = db.trait_solve(krate.into(), canonical)?;
76 82
@@ -88,14 +94,14 @@ fn deref_by_trait(
88 // the case. 94 // the case.
89 for i in 1..vars.0.num_vars { 95 for i in 1..vars.0.num_vars {
90 if vars.0.value[i] != Ty::Bound((i - 1) as u32) { 96 if vars.0.value[i] != Ty::Bound((i - 1) as u32) {
91 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty, solution); 97 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
92 return None; 98 return None;
93 } 99 }
94 } 100 }
95 Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars }) 101 Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars })
96 } 102 }
97 Solution::Ambig(_) => { 103 Solution::Ambig(_) => {
98 info!("Ambiguous solution for derefing {:?}: {:?}", ty, solution); 104 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution);
99 None 105 None
100 } 106 }
101 } 107 }
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 69b13baef..6fd00d457 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -22,6 +22,7 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
22use rustc_hash::FxHashMap; 22use rustc_hash::FxHashMap;
23 23
24use hir_def::{ 24use hir_def::{
25 data::{ConstData, FunctionData},
25 path::known, 26 path::known,
26 resolver::{HasResolver, Resolver, TypeNs}, 27 resolver::{HasResolver, Resolver, TypeNs},
27 type_ref::{Mutability, TypeRef}, 28 type_ref::{Mutability, TypeRef},
@@ -33,7 +34,6 @@ use ra_prof::profile;
33use test_utils::tested_by; 34use test_utils::tested_by;
34 35
35use super::{ 36use super::{
36 lower,
37 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 37 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
38 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, 38 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef,
39 TypeCtor, TypeWalk, Uncertain, 39 TypeCtor, TypeWalk, Uncertain,
@@ -43,8 +43,7 @@ use crate::{
43 db::HirDatabase, 43 db::HirDatabase,
44 expr::{BindingAnnotation, Body, ExprId, PatId}, 44 expr::{BindingAnnotation, Body, ExprId, PatId},
45 ty::infer::diagnostics::InferenceDiagnostic, 45 ty::infer::diagnostics::InferenceDiagnostic,
46 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, 46 Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, Trait, VariantDef,
47 StructField, Trait, VariantDef,
48}; 47};
49 48
50macro_rules! ty_app { 49macro_rules! ty_app {
@@ -68,10 +67,10 @@ pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResu
68 let resolver = DefWithBodyId::from(def).resolver(db); 67 let resolver = DefWithBodyId::from(def).resolver(db);
69 let mut ctx = InferenceContext::new(db, def, resolver); 68 let mut ctx = InferenceContext::new(db, def, resolver);
70 69
71 match def { 70 match &def {
72 DefWithBody::Const(ref c) => ctx.collect_const(&c.data(db)), 71 DefWithBody::Const(c) => ctx.collect_const(&db.const_data(c.id)),
73 DefWithBody::Function(ref f) => ctx.collect_fn(&f.data(db)), 72 DefWithBody::Function(f) => ctx.collect_fn(&db.function_data(f.id)),
74 DefWithBody::Static(ref s) => ctx.collect_const(&s.data(db)), 73 DefWithBody::Static(s) => ctx.collect_const(&db.static_data(s.id)),
75 } 74 }
76 75
77 ctx.infer_body(); 76 ctx.infer_body();
@@ -125,6 +124,8 @@ pub struct InferenceResult {
125 method_resolutions: FxHashMap<ExprId, Function>, 124 method_resolutions: FxHashMap<ExprId, Function>,
126 /// For each field access expr, records the field it resolves to. 125 /// For each field access expr, records the field it resolves to.
127 field_resolutions: FxHashMap<ExprId, StructField>, 126 field_resolutions: FxHashMap<ExprId, StructField>,
127 /// For each field in record literal, records the field it resolves to.
128 record_field_resolutions: FxHashMap<ExprId, StructField>,
128 /// For each struct literal, records the variant it resolves to. 129 /// For each struct literal, records the variant it resolves to.
129 variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>, 130 variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>,
130 /// For each associated item record what it resolves to 131 /// For each associated item record what it resolves to
@@ -142,6 +143,9 @@ impl InferenceResult {
142 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { 143 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> {
143 self.field_resolutions.get(&expr).copied() 144 self.field_resolutions.get(&expr).copied()
144 } 145 }
146 pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructField> {
147 self.record_field_resolutions.get(&expr).copied()
148 }
145 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> { 149 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> {
146 self.variant_resolutions.get(&id.into()).copied() 150 self.variant_resolutions.get(&id.into()).copied()
147 } 151 }
@@ -211,11 +215,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
211 var_unification_table: InPlaceUnificationTable::new(), 215 var_unification_table: InPlaceUnificationTable::new(),
212 obligations: Vec::default(), 216 obligations: Vec::default(),
213 return_ty: Ty::Unknown, // set in collect_fn_signature 217 return_ty: Ty::Unknown, // set in collect_fn_signature
214 trait_env: lower::trait_env(db, &resolver), 218 trait_env: TraitEnvironment::lower(db, &resolver),
215 coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), 219 coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver),
216 db, 220 db,
217 owner, 221 owner,
218 body: owner.body(db), 222 body: db.body(owner.into()),
219 resolver, 223 resolver,
220 } 224 }
221 } 225 }
@@ -559,21 +563,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
559 } 563 }
560 564
561 fn collect_const(&mut self, data: &ConstData) { 565 fn collect_const(&mut self, data: &ConstData) {
562 self.return_ty = self.make_ty(data.type_ref()); 566 self.return_ty = self.make_ty(&data.type_ref);
563 } 567 }
564 568
565 fn collect_fn(&mut self, data: &FnData) { 569 fn collect_fn(&mut self, data: &FunctionData) {
566 let body = Arc::clone(&self.body); // avoid borrow checker problem 570 let body = Arc::clone(&self.body); // avoid borrow checker problem
567 for (type_ref, pat) in data.params().iter().zip(body.params()) { 571 for (type_ref, pat) in data.params.iter().zip(body.params.iter()) {
568 let ty = self.make_ty(type_ref); 572 let ty = self.make_ty(type_ref);
569 573
570 self.infer_pat(*pat, &ty, BindingMode::default()); 574 self.infer_pat(*pat, &ty, BindingMode::default());
571 } 575 }
572 self.return_ty = self.make_ty(data.ret_type()); 576 self.return_ty = self.make_ty(&data.ret_type);
573 } 577 }
574 578
575 fn infer_body(&mut self) { 579 fn infer_body(&mut self) {
576 self.infer_expr(self.body.body_expr(), &Expectation::has_type(self.return_ty.clone())); 580 self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
577 } 581 }
578 582
579 fn resolve_into_iter_item(&self) -> Option<TypeAlias> { 583 fn resolve_into_iter_item(&self) -> Option<TypeAlias> {
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs
index 0772b9df5..4b53bba73 100644
--- a/crates/ra_hir/src/ty/infer/coerce.rs
+++ b/crates/ra_hir/src/ty/infer/coerce.rs
@@ -4,18 +4,17 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use hir_def::resolver::Resolver; 7use hir_def::{lang_item::LangItemTarget, resolver::Resolver};
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9use test_utils::tested_by; 9use test_utils::tested_by;
10 10
11use crate::{ 11use crate::{
12 db::HirDatabase, 12 db::HirDatabase,
13 lang_item::LangItemTarget,
14 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, 13 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk},
15 Adt, Mutability, 14 Adt, Mutability,
16}; 15};
17 16
18use super::{InferTy, InferenceContext, TypeVarValue}; 17use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue};
19 18
20impl<'a, D: HirDatabase> InferenceContext<'a, D> { 19impl<'a, D: HirDatabase> InferenceContext<'a, D> {
21 /// Unify two types, but may coerce the first one to the second one 20 /// Unify two types, but may coerce the first one to the second one
@@ -50,7 +49,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
50 ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { 49 ) -> FxHashMap<(TypeCtor, TypeCtor), usize> {
51 let krate = resolver.krate().unwrap(); 50 let krate = resolver.krate().unwrap();
52 let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) { 51 let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) {
53 Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate.into(), trait_), 52 Some(LangItemTarget::TraitId(trait_)) => {
53 db.impls_for_trait(krate.into(), trait_.into())
54 }
54 _ => return FxHashMap::default(), 55 _ => return FxHashMap::default(),
55 }; 56 };
56 57
@@ -244,14 +245,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
244 ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), 245 ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1),
245 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), 246 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2),
246 ) if struct1 == struct2 => { 247 ) if struct1 == struct2 => {
247 let fields = struct1.fields(self.db); 248 let field_tys = self.db.field_types(struct1.id.into());
248 let (last_field, prev_fields) = fields.split_last()?; 249 let struct_data = self.db.struct_data(struct1.id.0);
250
251 let mut fields = struct_data.variant_data.fields().iter();
252 let (last_field_id, _data) = fields.next_back()?;
249 253
250 // Get the generic parameter involved in the last field. 254 // Get the generic parameter involved in the last field.
251 let unsize_generic_index = { 255 let unsize_generic_index = {
252 let mut index = None; 256 let mut index = None;
253 let mut multiple_param = false; 257 let mut multiple_param = false;
254 last_field.ty(self.db).walk(&mut |ty| match ty { 258 field_tys[last_field_id].walk(&mut |ty| match ty {
255 &Ty::Param { idx, .. } => { 259 &Ty::Param { idx, .. } => {
256 if index.is_none() { 260 if index.is_none() {
257 index = Some(idx); 261 index = Some(idx);
@@ -270,8 +274,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
270 274
271 // Check other fields do not involve it. 275 // Check other fields do not involve it.
272 let mut multiple_used = false; 276 let mut multiple_used = false;
273 prev_fields.iter().for_each(|field| { 277 fields.for_each(|(field_id, _data)| {
274 field.ty(self.db).walk(&mut |ty| match ty { 278 field_tys[field_id].walk(&mut |ty| match ty {
275 &Ty::Param { idx, .. } if idx == unsize_generic_index => { 279 &Ty::Param { idx, .. } if idx == unsize_generic_index => {
276 multiple_used = true 280 multiple_used = true
277 } 281 }
@@ -316,9 +320,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
316 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone()); 320 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone());
317 let to_ty = self.resolve_ty_shallow(&to_ty); 321 let to_ty = self.resolve_ty_shallow(&to_ty);
318 // FIXME: Auto DerefMut 322 // FIXME: Auto DerefMut
319 for derefed_ty in 323 for derefed_ty in autoderef::autoderef(
320 autoderef::autoderef(self.db, &self.resolver.clone(), canonicalized.value.clone()) 324 self.db,
321 { 325 self.resolver.krate(),
326 InEnvironment {
327 value: canonicalized.value.clone(),
328 environment: self.trait_env.clone(),
329 },
330 ) {
322 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 331 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
323 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 332 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) {
324 // Stop when constructor matches. 333 // Stop when constructor matches.
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs
index ac570075f..194e55819 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -5,6 +5,7 @@ use std::sync::Arc;
5 5
6use hir_def::{ 6use hir_def::{
7 builtin_type::Signedness, 7 builtin_type::Signedness,
8 generics::GenericParams,
8 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
9 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
10}; 11};
@@ -13,11 +14,10 @@ use hir_expand::name;
13use crate::{ 14use crate::{
14 db::HirDatabase, 15 db::HirDatabase,
15 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 16 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
16 generics::{GenericParams, HasGenericParams},
17 ty::{ 17 ty::{
18 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, 18 autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy,
19 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 19 Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty,
20 Uncertain, 20 TypeCtor, TypeWalk, Uncertain,
21 }, 21 },
22 Adt, Name, 22 Adt, Name,
23}; 23};
@@ -214,19 +214,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
214 self.unify(&ty, &expected.ty); 214 self.unify(&ty, &expected.ty);
215 215
216 let substs = ty.substs().unwrap_or_else(Substs::empty); 216 let substs = ty.substs().unwrap_or_else(Substs::empty);
217 let field_types =
218 def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default();
217 for (field_idx, field) in fields.iter().enumerate() { 219 for (field_idx, field) in fields.iter().enumerate() {
218 let field_ty = def_id 220 let field_def = def_id.and_then(|it| match it.field(self.db, &field.name) {
219 .and_then(|it| match it.field(self.db, &field.name) { 221 Some(field) => Some(field),
220 Some(field) => Some(field), 222 None => {
221 None => { 223 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
222 self.push_diagnostic(InferenceDiagnostic::NoSuchField { 224 expr: tgt_expr,
223 expr: tgt_expr, 225 field: field_idx,
224 field: field_idx, 226 });
225 }); 227 None
226 None 228 }
227 } 229 });
228 }) 230 if let Some(field_def) = field_def {
229 .map_or(Ty::Unknown, |field| field.ty(self.db)) 231 self.result.record_field_resolutions.insert(field.expr, field_def);
232 }
233 let field_ty = field_def
234 .map_or(Ty::Unknown, |it| field_types[it.id].clone())
230 .subst(&substs); 235 .subst(&substs);
231 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 236 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
232 } 237 }
@@ -240,8 +245,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
240 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); 245 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty);
241 let ty = autoderef::autoderef( 246 let ty = autoderef::autoderef(
242 self.db, 247 self.db,
243 &self.resolver.clone(), 248 self.resolver.krate(),
244 canonicalized.value.clone(), 249 InEnvironment {
250 value: canonicalized.value.clone(),
251 environment: self.trait_env.clone(),
252 },
245 ) 253 )
246 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 254 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
247 Ty::Apply(a_ty) => match a_ty.ctor { 255 Ty::Apply(a_ty) => match a_ty.ctor {
@@ -250,7 +258,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
250 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 258 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()),
251 TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { 259 TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| {
252 self.write_field_resolution(tgt_expr, field); 260 self.write_field_resolution(tgt_expr, field);
253 field.ty(self.db).subst(&a_ty.parameters) 261 self.db.field_types(s.id.into())[field.id]
262 .clone()
263 .subst(&a_ty.parameters)
254 }), 264 }),
255 _ => None, 265 _ => None,
256 }, 266 },
@@ -330,16 +340,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
330 Expr::UnaryOp { expr, op } => { 340 Expr::UnaryOp { expr, op } => {
331 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 341 let inner_ty = self.infer_expr(*expr, &Expectation::none());
332 match op { 342 match op {
333 UnaryOp::Deref => { 343 UnaryOp::Deref => match self.resolver.krate() {
334 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); 344 Some(krate) => {
335 if let Some(derefed_ty) = 345 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty);
336 autoderef::deref(self.db, &self.resolver, &canonicalized.value) 346 match autoderef::deref(
337 { 347 self.db,
338 canonicalized.decanonicalize_ty(derefed_ty.value) 348 krate,
339 } else { 349 InEnvironment {
340 Ty::Unknown 350 value: &canonicalized.value,
351 environment: self.trait_env.clone(),
352 },
353 ) {
354 Some(derefed_ty) => {
355 canonicalized.decanonicalize_ty(derefed_ty.value)
356 }
357 None => Ty::Unknown,
358 }
341 } 359 }
342 } 360 None => Ty::Unknown,
361 },
343 UnaryOp::Neg => { 362 UnaryOp::Neg => {
344 match &inner_ty { 363 match &inner_ty {
345 Ty::Apply(a_ty) => match a_ty.ctor { 364 Ty::Apply(a_ty) => match a_ty.ctor {
@@ -534,7 +553,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
534 ( 553 (
535 ty, 554 ty,
536 self.db.type_for_def(func.into(), Namespace::Values), 555 self.db.type_for_def(func.into(), Namespace::Values),
537 Some(func.generic_params(self.db)), 556 Some(self.db.generic_params(func.id.into())),
538 ) 557 )
539 } 558 }
540 None => (receiver_ty, Ty::Unknown, None), 559 None => (receiver_ty, Ty::Unknown, None),
@@ -645,7 +664,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
645 if let Some(trait_) = f.parent_trait(self.db) { 664 if let Some(trait_) = f.parent_trait(self.db) {
646 // construct a TraitDef 665 // construct a TraitDef
647 let substs = a_ty.parameters.prefix( 666 let substs = a_ty.parameters.prefix(
648 trait_.generic_params(self.db).count_params_including_parent(), 667 self.db
668 .generic_params(trait_.id.into())
669 .count_params_including_parent(),
649 ); 670 );
650 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); 671 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
651 } 672 }
diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir/src/ty/infer/pat.rs
index c125ddfbc..641d61e87 100644
--- a/crates/ra_hir/src/ty/infer/pat.rs
+++ b/crates/ra_hir/src/ty/infer/pat.rs
@@ -27,10 +27,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
27 27
28 let substs = ty.substs().unwrap_or_else(Substs::empty); 28 let substs = ty.substs().unwrap_or_else(Substs::empty);
29 29
30 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default();
30 for (i, &subpat) in subpats.iter().enumerate() { 31 for (i, &subpat) in subpats.iter().enumerate() {
31 let expected_ty = def 32 let expected_ty = def
32 .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) 33 .and_then(|d| d.field(self.db, &Name::new_tuple_field(i)))
33 .map_or(Ty::Unknown, |field| field.ty(self.db)) 34 .map_or(Ty::Unknown, |field| field_tys[field.id].clone())
34 .subst(&substs); 35 .subst(&substs);
35 let expected_ty = self.normalize_associated_types_in(expected_ty); 36 let expected_ty = self.normalize_associated_types_in(expected_ty);
36 self.infer_pat(subpat, &expected_ty, default_bm); 37 self.infer_pat(subpat, &expected_ty, default_bm);
@@ -56,10 +57,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
56 57
57 let substs = ty.substs().unwrap_or_else(Substs::empty); 58 let substs = ty.substs().unwrap_or_else(Substs::empty);
58 59
60 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default();
59 for subpat in subpats { 61 for subpat in subpats {
60 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); 62 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name));
61 let expected_ty = 63 let expected_ty = matching_field
62 matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs); 64 .map_or(Ty::Unknown, |field| field_tys[field.id].clone())
65 .subst(&substs);
63 let expected_ty = self.normalize_associated_types_in(expected_ty); 66 let expected_ty = self.normalize_associated_types_in(expected_ty);
64 self.infer_pat(subpat.pat, &expected_ty, default_bm); 67 self.infer_pat(subpat.pat, &expected_ty, default_bm);
65 } 68 }
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs
index 70136e514..6165eba4f 100644
--- a/crates/ra_hir/src/ty/infer/path.rs
+++ b/crates/ra_hir/src/ty/infer/path.rs
@@ -7,7 +7,6 @@ use hir_def::{
7 7
8use crate::{ 8use crate::{
9 db::HirDatabase, 9 db::HirDatabase,
10 generics::HasGenericParams,
11 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, 10 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk},
12 AssocItem, Container, Function, Name, Path, 11 AssocItem, Container, Function, Name, Path,
13}; 12};
@@ -204,7 +203,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
204 Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()), 203 Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()),
205 Container::Trait(t) => { 204 Container::Trait(t) => {
206 // we're picking this method 205 // we're picking this method
207 let trait_substs = Substs::build_for_def(self.db, t) 206 let trait_substs = Substs::build_for_def(self.db, t.id)
208 .push(ty.clone()) 207 .push(ty.clone())
209 .fill(std::iter::repeat_with(|| self.new_type_var())) 208 .fill(std::iter::repeat_with(|| self.new_type_var()))
210 .build(); 209 .build();
@@ -230,7 +229,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
230 if let ValueNs::FunctionId(func) = def { 229 if let ValueNs::FunctionId(func) = def {
231 let func = Function::from(*func); 230 let func = Function::from(*func);
232 // We only do the infer if parent has generic params 231 // We only do the infer if parent has generic params
233 let gen = func.generic_params(self.db); 232 let gen = self.db.generic_params(func.id.into());
234 if gen.count_parent_params() == 0 { 233 if gen.count_parent_params() == 0 {
235 return None; 234 return None;
236 } 235 }
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index c6ad0811b..1ceafd9b1 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -10,27 +10,27 @@ use std::sync::Arc;
10 10
11use hir_def::{ 11use hir_def::{
12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, 12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType},
13 generics::WherePredicate,
13 path::{GenericArg, PathSegment}, 14 path::{GenericArg, PathSegment},
14 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
15 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
16 GenericDefId, 17 AdtId, EnumVariantId, GenericDefId, LocalStructFieldId, VariantId,
17}; 18};
19use ra_arena::map::ArenaMap;
18 20
19use super::{ 21use super::{
20 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 22 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef,
21 TypeWalk, 23 Ty, TypeCtor, TypeWalk,
22}; 24};
23use crate::{ 25use crate::{
24 db::HirDatabase, 26 db::HirDatabase,
25 generics::HasGenericParams,
26 generics::{GenericDef, WherePredicate},
27 ty::{ 27 ty::{
28 primitive::{FloatTy, IntTy, Uncertain}, 28 primitive::{FloatTy, IntTy, Uncertain},
29 Adt, 29 Adt,
30 }, 30 },
31 util::make_mut_slice, 31 util::make_mut_slice,
32 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, StructField, 32 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait,
33 Trait, TypeAlias, Union, VariantDef, 33 TypeAlias, Union,
34}; 34};
35 35
36// FIXME: this is only really used in `type_for_def`, which contains a bunch of 36// FIXME: this is only really used in `type_for_def`, which contains a bunch of
@@ -261,8 +261,10 @@ impl Ty {
261 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); 261 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db));
262 for t in traits { 262 for t in traits {
263 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { 263 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) {
264 let substs = 264 let substs = Substs::build_for_def(db, t.id)
265 Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); 265 .push(self_ty.clone())
266 .fill_with_unknown()
267 .build();
266 // FIXME handle type parameters on the segment 268 // FIXME handle type parameters on the segment
267 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); 269 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs });
268 } 270 }
@@ -287,11 +289,11 @@ impl Ty {
287 segment: &PathSegment, 289 segment: &PathSegment,
288 resolved: TypableDef, 290 resolved: TypableDef,
289 ) -> Substs { 291 ) -> Substs {
290 let def_generic: Option<GenericDef> = match resolved { 292 let def_generic: Option<GenericDefId> = match resolved {
291 TypableDef::Function(func) => Some(func.into()), 293 TypableDef::Function(func) => Some(func.id.into()),
292 TypableDef::Adt(adt) => Some(adt.into()), 294 TypableDef::Adt(adt) => Some(adt.into()),
293 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()), 295 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()),
294 TypableDef::TypeAlias(t) => Some(t.into()), 296 TypableDef::TypeAlias(t) => Some(t.id.into()),
295 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, 297 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None,
296 }; 298 };
297 substs_from_path_segment(db, resolver, segment, def_generic, false) 299 substs_from_path_segment(db, resolver, segment, def_generic, false)
@@ -338,11 +340,11 @@ pub(super) fn substs_from_path_segment(
338 db: &impl HirDatabase, 340 db: &impl HirDatabase,
339 resolver: &Resolver, 341 resolver: &Resolver,
340 segment: &PathSegment, 342 segment: &PathSegment,
341 def_generic: Option<GenericDef>, 343 def_generic: Option<GenericDefId>,
342 add_self_param: bool, 344 add_self_param: bool,
343) -> Substs { 345) -> Substs {
344 let mut substs = Vec::new(); 346 let mut substs = Vec::new();
345 let def_generics = def_generic.map(|def| def.generic_params(db)); 347 let def_generics = def_generic.map(|def| db.generic_params(def.into()));
346 348
347 let (parent_param_count, param_count) = 349 let (parent_param_count, param_count) =
348 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); 350 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len()));
@@ -376,7 +378,7 @@ pub(super) fn substs_from_path_segment(
376 378
377 // handle defaults 379 // handle defaults
378 if let Some(def_generic) = def_generic { 380 if let Some(def_generic) = def_generic {
379 let default_substs = db.generic_defaults(def_generic); 381 let default_substs = db.generic_defaults(def_generic.into());
380 assert_eq!(substs.len(), default_substs.len()); 382 assert_eq!(substs.len(), default_substs.len());
381 383
382 for (i, default_ty) in default_substs.iter().enumerate() { 384 for (i, default_ty) in default_substs.iter().enumerate() {
@@ -439,11 +441,11 @@ impl TraitRef {
439 ) -> Substs { 441 ) -> Substs {
440 let has_self_param = 442 let has_self_param =
441 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); 443 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false);
442 substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) 444 substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param)
443 } 445 }
444 446
445 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { 447 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef {
446 let substs = Substs::identity(&trait_.generic_params(db)); 448 let substs = Substs::identity(&db.generic_params(trait_.id.into()));
447 TraitRef { trait_, substs } 449 TraitRef { trait_, substs }
448 } 450 }
449 451
@@ -550,16 +552,23 @@ pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSi
550 } 552 }
551} 553}
552 554
553/// Build the type of a specific field of a struct or enum variant. 555/// Build the type of all specific fields of a struct or enum variant.
554pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 556pub(crate) fn field_types_query(
555 let parent_def = field.parent_def(db); 557 db: &impl HirDatabase,
556 let resolver = match parent_def { 558 variant_id: VariantId,
557 VariantDef::Struct(it) => it.id.resolver(db), 559) -> Arc<ArenaMap<LocalStructFieldId, Ty>> {
558 VariantDef::EnumVariant(it) => it.parent.id.resolver(db), 560 let (resolver, var_data) = match variant_id {
561 VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()),
562 VariantId::EnumVariantId(it) => (
563 it.parent.resolver(db),
564 db.enum_data(it.parent).variants[it.local_id].variant_data.clone(),
565 ),
559 }; 566 };
560 let var_data = parent_def.variant_data(db); 567 let mut res = ArenaMap::default();
561 let type_ref = &var_data.fields().unwrap()[field.id].type_ref; 568 for (field_id, field_data) in var_data.fields().iter() {
562 Ty::from_hir(db, &resolver, type_ref) 569 res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref))
570 }
571 Arc::new(res)
563} 572}
564 573
565/// This query exists only to be used when resolving short-hand associated types 574/// This query exists only to be used when resolving short-hand associated types
@@ -572,10 +581,10 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
572/// these are fine: `T: Foo<U::Item>, U: Foo<()>`. 581/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
573pub(crate) fn generic_predicates_for_param_query( 582pub(crate) fn generic_predicates_for_param_query(
574 db: &impl HirDatabase, 583 db: &impl HirDatabase,
575 def: GenericDef, 584 def: GenericDefId,
576 param_idx: u32, 585 param_idx: u32,
577) -> Arc<[GenericPredicate]> { 586) -> Arc<[GenericPredicate]> {
578 let resolver = GenericDefId::from(def).resolver(db); 587 let resolver = def.resolver(db);
579 resolver 588 resolver
580 .where_predicates_in_scope() 589 .where_predicates_in_scope()
581 // we have to filter out all other predicates *first*, before attempting to lower them 590 // we have to filter out all other predicates *first*, before attempting to lower them
@@ -584,24 +593,23 @@ pub(crate) fn generic_predicates_for_param_query(
584 .collect() 593 .collect()
585} 594}
586 595
587pub(crate) fn trait_env( 596impl TraitEnvironment {
588 db: &impl HirDatabase, 597 pub(crate) fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
589 resolver: &Resolver, 598 let predicates = resolver
590) -> Arc<super::TraitEnvironment> { 599 .where_predicates_in_scope()
591 let predicates = resolver 600 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
592 .where_predicates_in_scope() 601 .collect::<Vec<_>>();
593 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
594 .collect::<Vec<_>>();
595 602
596 Arc::new(super::TraitEnvironment { predicates }) 603 Arc::new(TraitEnvironment { predicates })
604 }
597} 605}
598 606
599/// Resolve the where clause(s) of an item with generics. 607/// Resolve the where clause(s) of an item with generics.
600pub(crate) fn generic_predicates_query( 608pub(crate) fn generic_predicates_query(
601 db: &impl HirDatabase, 609 db: &impl HirDatabase,
602 def: GenericDef, 610 def: GenericDefId,
603) -> Arc<[GenericPredicate]> { 611) -> Arc<[GenericPredicate]> {
604 let resolver = GenericDefId::from(def).resolver(db); 612 let resolver = def.resolver(db);
605 resolver 613 resolver
606 .where_predicates_in_scope() 614 .where_predicates_in_scope()
607 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 615 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
@@ -609,9 +617,9 @@ pub(crate) fn generic_predicates_query(
609} 617}
610 618
611/// Resolve the default type params from generics 619/// Resolve the default type params from generics
612pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { 620pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs {
613 let resolver = GenericDefId::from(def).resolver(db); 621 let resolver = def.resolver(db);
614 let generic_params = def.generic_params(db); 622 let generic_params = db.generic_params(def.into());
615 623
616 let defaults = generic_params 624 let defaults = generic_params
617 .params_including_parent() 625 .params_including_parent()
@@ -623,35 +631,35 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
623} 631}
624 632
625fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 633fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
626 let data = def.data(db); 634 let data = db.function_data(def.id);
627 let resolver = def.id.resolver(db); 635 let resolver = def.id.resolver(db);
628 let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 636 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
629 let ret = Ty::from_hir(db, &resolver, data.ret_type()); 637 let ret = Ty::from_hir(db, &resolver, &data.ret_type);
630 FnSig::from_params_and_return(params, ret) 638 FnSig::from_params_and_return(params, ret)
631} 639}
632 640
633/// Build the declared type of a function. This should not need to look at the 641/// Build the declared type of a function. This should not need to look at the
634/// function body. 642/// function body.
635fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 643fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
636 let generics = def.generic_params(db); 644 let generics = db.generic_params(def.id.into());
637 let substs = Substs::identity(&generics); 645 let substs = Substs::identity(&generics);
638 Ty::apply(TypeCtor::FnDef(def.into()), substs) 646 Ty::apply(TypeCtor::FnDef(def.into()), substs)
639} 647}
640 648
641/// Build the declared type of a const. 649/// Build the declared type of a const.
642fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { 650fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty {
643 let data = def.data(db); 651 let data = db.const_data(def.id);
644 let resolver = def.id.resolver(db); 652 let resolver = def.id.resolver(db);
645 653
646 Ty::from_hir(db, &resolver, data.type_ref()) 654 Ty::from_hir(db, &resolver, &data.type_ref)
647} 655}
648 656
649/// Build the declared type of a static. 657/// Build the declared type of a static.
650fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { 658fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty {
651 let data = def.data(db); 659 let data = db.static_data(def.id);
652 let resolver = def.id.resolver(db); 660 let resolver = def.id.resolver(db);
653 661
654 Ty::from_hir(db, &resolver, data.type_ref()) 662 Ty::from_hir(db, &resolver, &data.type_ref)
655} 663}
656 664
657/// Build the declared type of a static. 665/// Build the declared type of a static.
@@ -697,10 +705,7 @@ impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
697 705
698fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { 706fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
699 let struct_data = db.struct_data(def.id.into()); 707 let struct_data = db.struct_data(def.id.into());
700 let fields = match struct_data.variant_data.fields() { 708 let fields = struct_data.variant_data.fields();
701 Some(fields) => fields,
702 None => panic!("fn_sig_for_struct_constructor called on unit struct"),
703 };
704 let resolver = def.id.resolver(db); 709 let resolver = def.id.resolver(db);
705 let params = fields 710 let params = fields
706 .iter() 711 .iter()
@@ -713,26 +718,23 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
713/// Build the type of a tuple struct constructor. 718/// Build the type of a tuple struct constructor.
714fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { 719fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
715 let struct_data = db.struct_data(def.id.into()); 720 let struct_data = db.struct_data(def.id.into());
716 if struct_data.variant_data.fields().is_none() { 721 if struct_data.variant_data.is_unit() {
717 return type_for_adt(db, def); // Unit struct 722 return type_for_adt(db, def); // Unit struct
718 } 723 }
719 let generics = def.generic_params(db); 724 let generics = db.generic_params(def.id.into());
720 let substs = Substs::identity(&generics); 725 let substs = Substs::identity(&generics);
721 Ty::apply(TypeCtor::FnDef(def.into()), substs) 726 Ty::apply(TypeCtor::FnDef(def.into()), substs)
722} 727}
723 728
724fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { 729fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig {
725 let var_data = def.variant_data(db); 730 let var_data = def.variant_data(db);
726 let fields = match var_data.fields() { 731 let fields = var_data.fields();
727 Some(fields) => fields,
728 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"),
729 };
730 let resolver = def.parent.id.resolver(db); 732 let resolver = def.parent.id.resolver(db);
731 let params = fields 733 let params = fields
732 .iter() 734 .iter()
733 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 735 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
734 .collect::<Vec<_>>(); 736 .collect::<Vec<_>>();
735 let generics = def.parent_enum(db).generic_params(db); 737 let generics = db.generic_params(def.parent_enum(db).id.into());
736 let substs = Substs::identity(&generics); 738 let substs = Substs::identity(&generics);
737 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); 739 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs);
738 FnSig::from_params_and_return(params, ret) 740 FnSig::from_params_and_return(params, ret)
@@ -741,21 +743,23 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
741/// Build the type of a tuple enum variant constructor. 743/// Build the type of a tuple enum variant constructor.
742fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { 744fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
743 let var_data = def.variant_data(db); 745 let var_data = def.variant_data(db);
744 if var_data.fields().is_none() { 746 if var_data.is_unit() {
745 return type_for_adt(db, def.parent_enum(db)); // Unit variant 747 return type_for_adt(db, def.parent_enum(db)); // Unit variant
746 } 748 }
747 let generics = def.parent_enum(db).generic_params(db); 749 let generics = db.generic_params(def.parent_enum(db).id.into());
748 let substs = Substs::identity(&generics); 750 let substs = Substs::identity(&generics);
749 Ty::apply(TypeCtor::FnDef(def.into()), substs) 751 Ty::apply(TypeCtor::FnDef(def.into()), substs)
750} 752}
751 753
752fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt> + HasGenericParams) -> Ty { 754fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty {
753 let generics = adt.generic_params(db); 755 let adt = adt.into();
754 Ty::apply(TypeCtor::Adt(adt.into()), Substs::identity(&generics)) 756 let adt_id: AdtId = adt.into();
757 let generics = db.generic_params(adt_id.into());
758 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics))
755} 759}
756 760
757fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 761fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
758 let generics = t.generic_params(db); 762 let generics = db.generic_params(t.id.into());
759 let resolver = t.id.resolver(db); 763 let resolver = t.id.resolver(db);
760 let type_ref = t.type_ref(db); 764 let type_ref = t.type_ref(db);
761 let substs = Substs::identity(&generics); 765 let substs = Substs::identity(&generics);
@@ -817,12 +821,12 @@ impl CallableDef {
817 } 821 }
818} 822}
819 823
820impl From<CallableDef> for GenericDef { 824impl From<CallableDef> for GenericDefId {
821 fn from(def: CallableDef) -> GenericDef { 825 fn from(def: CallableDef) -> GenericDefId {
822 match def { 826 match def {
823 CallableDef::Function(f) => f.into(), 827 CallableDef::Function(f) => f.id.into(),
824 CallableDef::Struct(s) => s.into(), 828 CallableDef::Struct(s) => s.id.into(),
825 CallableDef::EnumVariant(e) => e.into(), 829 CallableDef::EnumVariant(e) => EnumVariantId::from(e).into(),
826 } 830 }
827 } 831 }
828} 832}
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 64adb814d..c5ab690eb 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -5,7 +5,7 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::resolver::Resolver; 8use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef};
9use rustc_hash::FxHashMap; 9use rustc_hash::FxHashMap;
10 10
11use crate::{ 11use crate::{
@@ -15,7 +15,7 @@ use crate::{
15 AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, 15 AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait,
16}; 16};
17 17
18use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; 18use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
19 19
20/// This is used as a key for indexing impls. 20/// This is used as a key for indexing impls.
21#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 21#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -91,34 +91,43 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayV
91 // Types like slice can have inherent impls in several crates, (core and alloc). 91 // Types like slice can have inherent impls in several crates, (core and alloc).
92 // The corresponding impls are marked with lang items, so we can use them to find the required crates. 92 // The corresponding impls are marked with lang items, so we can use them to find the required crates.
93 macro_rules! lang_item_crate { 93 macro_rules! lang_item_crate {
94 ($db:expr, $cur_crate:expr, $($name:expr),+ $(,)?) => {{ 94 ($($name:expr),+ $(,)?) => {{
95 let mut v = ArrayVec::<[Crate; 2]>::new(); 95 let mut v = ArrayVec::<[LangItemTarget; 2]>::new();
96 $( 96 $(
97 v.extend($db.lang_item($cur_crate, $name.into()).and_then(|item| item.krate($db))); 97 v.extend(db.lang_item(cur_crate.crate_id, $name.into()));
98 )+ 98 )+
99 Some(v) 99 v
100 }}; 100 }};
101 } 101 }
102 102
103 match ty { 103 let lang_item_targets = match ty {
104 Ty::Apply(a_ty) => match a_ty.ctor { 104 Ty::Apply(a_ty) => match a_ty.ctor {
105 TypeCtor::Adt(def_id) => Some(std::iter::once(def_id.krate(db)?).collect()), 105 TypeCtor::Adt(def_id) => return Some(std::iter::once(def_id.krate(db)?).collect()),
106 TypeCtor::Bool => lang_item_crate!(db, cur_crate, "bool"), 106 TypeCtor::Bool => lang_item_crate!("bool"),
107 TypeCtor::Char => lang_item_crate!(db, cur_crate, "char"), 107 TypeCtor::Char => lang_item_crate!("char"),
108 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { 108 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness {
109 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 109 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
110 FloatBitness::X32 => lang_item_crate!(db, cur_crate, "f32", "f32_runtime"), 110 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"),
111 FloatBitness::X64 => lang_item_crate!(db, cur_crate, "f64", "f64_runtime"), 111 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
112 }, 112 },
113 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(db, cur_crate, i.ty_to_string()), 113 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()),
114 TypeCtor::Str => lang_item_crate!(db, cur_crate, "str_alloc", "str"), 114 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
115 TypeCtor::Slice => lang_item_crate!(db, cur_crate, "slice_alloc", "slice"), 115 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
116 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!(db, cur_crate, "const_ptr"), 116 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
117 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!(db, cur_crate, "mut_ptr"), 117 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
118 _ => None, 118 _ => return None,
119 }, 119 },
120 _ => None, 120 _ => return None,
121 } 121 };
122 let res = lang_item_targets
123 .into_iter()
124 .filter_map(|it| match it {
125 LangItemTarget::ImplBlockId(it) => Some(it),
126 _ => None,
127 })
128 .map(|it| it.module(db).krate.into())
129 .collect();
130 Some(res)
122} 131}
123 132
124/// Look up the method with the given name, returning the actual autoderefed 133/// Look up the method with the given name, returning the actual autoderefed
@@ -170,8 +179,9 @@ pub(crate) fn iterate_method_candidates<T>(
170 // Also note that when we've got a receiver like &S, even if the method we 179 // Also note that when we've got a receiver like &S, even if the method we
171 // find in the end takes &self, we still do the autoderef step (just as 180 // find in the end takes &self, we still do the autoderef step (just as
172 // rustc does an autoderef and then autoref again). 181 // rustc does an autoderef and then autoref again).
173 182 let environment = TraitEnvironment::lower(db, resolver);
174 for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { 183 let ty = InEnvironment { value: ty.clone(), environment };
184 for derefed_ty in autoderef::autoderef(db, resolver.krate(), ty) {
175 if let Some(result) = iterate_inherent_methods( 185 if let Some(result) = iterate_inherent_methods(
176 &derefed_ty, 186 &derefed_ty,
177 db, 187 db,
@@ -221,7 +231,7 @@ fn iterate_trait_method_candidates<T>(
221) -> Option<T> { 231) -> Option<T> {
222 let krate = resolver.krate()?; 232 let krate = resolver.krate()?;
223 // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) 233 // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that)
224 let env = lower::trait_env(db, resolver); 234 let env = TraitEnvironment::lower(db, resolver);
225 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope 235 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope
226 let inherent_trait = ty.value.inherent_trait().into_iter(); 236 let inherent_trait = ty.value.inherent_trait().into_iter();
227 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 237 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
@@ -233,7 +243,7 @@ fn iterate_trait_method_candidates<T>(
233 .chain(traits_from_env) 243 .chain(traits_from_env)
234 .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); 244 .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from));
235 'traits: for t in traits { 245 'traits: for t in traits {
236 let data = t.trait_data(db); 246 let data = db.trait_data(t.id);
237 247
238 // we'll be lazy about checking whether the type implements the 248 // we'll be lazy about checking whether the type implements the
239 // trait, but if we find out it doesn't, we'll skip the rest of the 249 // trait, but if we find out it doesn't, we'll skip the rest of the
@@ -291,9 +301,9 @@ fn is_valid_candidate(
291) -> bool { 301) -> bool {
292 match item { 302 match item {
293 AssocItem::Function(m) => { 303 AssocItem::Function(m) => {
294 let data = m.data(db); 304 let data = db.function_data(m.id);
295 name.map_or(true, |name| data.name() == name) 305 name.map_or(true, |name| data.name == *name)
296 && (data.has_self_param() || mode == LookupMode::Path) 306 && (data.has_self_param || mode == LookupMode::Path)
297 } 307 }
298 AssocItem::Const(c) => { 308 AssocItem::Const(c) => {
299 name.map_or(true, |name| Some(name) == c.name(db).as_ref()) 309 name.map_or(true, |name| Some(name) == c.name(db).as_ref())
@@ -315,7 +325,7 @@ pub(crate) fn implements_trait(
315 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet 325 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
316 return true; 326 return true;
317 } 327 }
318 let env = lower::trait_env(db, resolver); 328 let env = TraitEnvironment::lower(db, resolver);
319 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 329 let goal = generic_implements_goal(db, env, trait_, ty.clone());
320 let solution = db.trait_solve(krate, goal); 330 let solution = db.trait_solve(krate, goal);
321 331
@@ -355,7 +365,7 @@ fn generic_implements_goal(
355 self_ty: Canonical<Ty>, 365 self_ty: Canonical<Ty>,
356) -> Canonical<InEnvironment<super::Obligation>> { 366) -> Canonical<InEnvironment<super::Obligation>> {
357 let num_vars = self_ty.num_vars; 367 let num_vars = self_ty.num_vars;
358 let substs = super::Substs::build_for_def(db, trait_) 368 let substs = super::Substs::build_for_def(db, trait_.id)
359 .push(self_ty.value) 369 .push(self_ty.value)
360 .fill_with_bound_vars(num_vars as u32) 370 .fill_with_bound_vars(num_vars as u32)
361 .build(); 371 .build();
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 74c12a0a2..3209c66bd 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -2550,8 +2550,6 @@ fn test() {
2550 [233; 246) 'GLOBAL_STATIC': u32 2550 [233; 246) 'GLOBAL_STATIC': u32
2551 [256; 257) 'w': u32 2551 [256; 257) 'w': u32
2552 [260; 277) 'GLOBAL...IC_MUT': u32 2552 [260; 277) 'GLOBAL...IC_MUT': u32
2553 [118; 120) '99': u32
2554 [161; 163) '99': u32
2555 "### 2553 "###
2556 ); 2554 );
2557} 2555}
@@ -4857,3 +4855,41 @@ fn main() {
4857 "### 4855 "###
4858 ); 4856 );
4859} 4857}
4858
4859#[test]
4860fn infer_builtin_macros_file() {
4861 assert_snapshot!(
4862 infer(r#"
4863#[rustc_builtin_macro]
4864macro_rules! file {() => {}}
4865
4866fn main() {
4867 let x = file!();
4868}
4869"#),
4870 @r###"
4871 ![0; 2) '""': &str
4872 [64; 88) '{ ...!(); }': ()
4873 [74; 75) 'x': &str
4874 "###
4875 );
4876}
4877
4878#[test]
4879fn infer_builtin_macros_column() {
4880 assert_snapshot!(
4881 infer(r#"
4882#[rustc_builtin_macro]
4883macro_rules! column {() => {}}
4884
4885fn main() {
4886 let x = column!();
4887}
4888"#),
4889 @r###"
4890 ![0; 2) '13': i32
4891 [66; 92) '{ ...!(); }': ()
4892 [76; 77) 'x': i32
4893 "###
4894 );
4895}
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs
index 45f725438..268fa09e4 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir/src/ty/traits.rs
@@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex};
3 3
4use chalk_ir::{cast::Cast, family::ChalkIr}; 4use chalk_ir::{cast::Cast, family::ChalkIr};
5use log::debug; 5use log::debug;
6use ra_db::salsa; 6use ra_db::{impl_intern_key, salsa};
7use ra_prof::profile; 7use ra_prof::profile;
8use rustc_hash::FxHashSet; 8use rustc_hash::FxHashSet;
9 9
@@ -304,6 +304,10 @@ pub enum Impl {
304 /// Closure types implement the Fn traits synthetically. 304 /// Closure types implement the Fn traits synthetically.
305 ClosureFnTraitImpl(ClosureFnTraitImplData), 305 ClosureFnTraitImpl(ClosureFnTraitImplData),
306} 306}
307/// This exists just for Chalk, because our ImplIds are only unique per module.
308#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
309pub struct GlobalImplId(salsa::InternId);
310impl_intern_key!(GlobalImplId);
307 311
308/// An associated type value. Usually this comes from a `type` declaration 312/// An associated type value. Usually this comes from a `type` declaration
309/// inside an impl block, but for built-in impls we have to synthesize it. 313/// inside an impl block, but for built-in impls we have to synthesize it.
@@ -315,3 +319,8 @@ pub enum AssocTyValue {
315 /// The output type of the Fn trait implementation. 319 /// The output type of the Fn trait implementation.
316 ClosureFnTraitImplOutput(ClosureFnTraitImplData), 320 ClosureFnTraitImplOutput(ClosureFnTraitImplData),
317} 321}
322/// This exists just for Chalk, because it needs a unique ID for each associated
323/// type value in an impl (even synthetic ones).
324#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
325pub struct AssocTyValueId(salsa::InternId);
326impl_intern_key!(AssocTyValueId);
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 9bf93981a..0272dd9ae 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -9,6 +9,7 @@ use chalk_ir::{
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11 11
12use hir_def::{lang_item::LangItemTarget, GenericDefId};
12use hir_expand::name; 13use hir_expand::name;
13 14
14use ra_db::salsa::{InternId, InternKey}; 15use ra_db::salsa::{InternId, InternKey};
@@ -16,10 +17,9 @@ use ra_db::salsa::{InternId, InternKey};
16use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 17use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
17use crate::{ 18use crate::{
18 db::HirDatabase, 19 db::HirDatabase,
19 generics::{GenericDef, HasGenericParams},
20 ty::display::HirDisplay, 20 ty::display::HirDisplay,
21 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, 21 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
22 Crate, HasBody, ImplBlock, Trait, TypeAlias, 22 Crate, ImplBlock, Trait, TypeAlias,
23}; 23};
24 24
25/// This represents a trait whose name we could not resolve. 25/// This represents a trait whose name we could not resolve.
@@ -402,7 +402,7 @@ fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
402 402
403fn convert_where_clauses( 403fn convert_where_clauses(
404 db: &impl HirDatabase, 404 db: &impl HirDatabase,
405 def: GenericDef, 405 def: GenericDefId,
406 substs: &Substs, 406 substs: &Substs,
407) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> { 407) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> {
408 let generic_predicates = db.generic_predicates(def); 408 let generic_predicates = db.generic_predicates(def);
@@ -509,7 +509,7 @@ pub(crate) fn associated_ty_data_query(
509 Some(crate::Container::Trait(t)) => t, 509 Some(crate::Container::Trait(t)) => t,
510 _ => panic!("associated type not in trait"), 510 _ => panic!("associated type not in trait"),
511 }; 511 };
512 let generic_params = type_alias.generic_params(db); 512 let generic_params = db.generic_params(type_alias.id.into());
513 let bound_data = chalk_rust_ir::AssociatedTyDatumBound { 513 let bound_data = chalk_rust_ir::AssociatedTyDatumBound {
514 // FIXME add bounds and where clauses 514 // FIXME add bounds and where clauses
515 bounds: vec![], 515 bounds: vec![],
@@ -550,7 +550,7 @@ pub(crate) fn trait_datum_query(
550 } 550 }
551 let trait_: Trait = from_chalk(db, trait_id); 551 let trait_: Trait = from_chalk(db, trait_id);
552 debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); 552 debug!("trait {:?} = {:?}", trait_id, trait_.name(db));
553 let generic_params = trait_.generic_params(db); 553 let generic_params = db.generic_params(trait_.id.into());
554 let bound_vars = Substs::bound_vars(&generic_params); 554 let bound_vars = Substs::bound_vars(&generic_params);
555 let flags = chalk_rust_ir::TraitFlags { 555 let flags = chalk_rust_ir::TraitFlags {
556 auto: trait_.is_auto(db), 556 auto: trait_.is_auto(db),
@@ -561,7 +561,7 @@ pub(crate) fn trait_datum_query(
561 marker: false, 561 marker: false,
562 fundamental: false, 562 fundamental: false,
563 }; 563 };
564 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); 564 let where_clauses = convert_where_clauses(db, trait_.id.into(), &bound_vars);
565 let associated_ty_ids = trait_ 565 let associated_ty_ids = trait_
566 .items(db) 566 .items(db)
567 .into_iter() 567 .into_iter()
@@ -594,7 +594,7 @@ pub(crate) fn struct_datum_query(
594 let where_clauses = type_ctor 594 let where_clauses = type_ctor
595 .as_generic_def() 595 .as_generic_def()
596 .map(|generic_def| { 596 .map(|generic_def| {
597 let generic_params = generic_def.generic_params(db); 597 let generic_params = db.generic_params(generic_def.into());
598 let bound_vars = Substs::bound_vars(&generic_params); 598 let bound_vars = Substs::bound_vars(&generic_params);
599 convert_where_clauses(db, generic_def, &bound_vars) 599 convert_where_clauses(db, generic_def, &bound_vars)
600 }) 600 })
@@ -634,7 +634,7 @@ fn impl_block_datum(
634 impl_id: ImplId, 634 impl_id: ImplId,
635 impl_block: ImplBlock, 635 impl_block: ImplBlock,
636) -> Option<Arc<ImplDatum<ChalkIr>>> { 636) -> Option<Arc<ImplDatum<ChalkIr>>> {
637 let generic_params = impl_block.generic_params(db); 637 let generic_params = db.generic_params(impl_block.id.into());
638 let bound_vars = Substs::bound_vars(&generic_params); 638 let bound_vars = Substs::bound_vars(&generic_params);
639 let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); 639 let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars);
640 let trait_ = trait_ref.trait_; 640 let trait_ = trait_ref.trait_;
@@ -643,7 +643,7 @@ fn impl_block_datum(
643 } else { 643 } else {
644 chalk_rust_ir::ImplType::External 644 chalk_rust_ir::ImplType::External
645 }; 645 };
646 let where_clauses = convert_where_clauses(db, impl_block.into(), &bound_vars); 646 let where_clauses = convert_where_clauses(db, impl_block.id.into(), &bound_vars);
647 let negative = impl_block.is_negative(db); 647 let negative = impl_block.is_negative(db);
648 debug!( 648 debug!(
649 "impl {:?}: {}{} where {:?}", 649 "impl {:?}: {}{} where {:?}",
@@ -715,7 +715,7 @@ fn closure_fn_trait_impl_datum(
715 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; 715 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
716 fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?; 716 fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?;
717 717
718 let num_args: u16 = match &data.def.body(db)[data.expr] { 718 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
719 crate::expr::Expr::Lambda { args, .. } => args.len() as u16, 719 crate::expr::Expr::Lambda { args, .. } => args.len() as u16,
720 _ => { 720 _ => {
721 log::warn!("closure for closure type {:?} not found", data); 721 log::warn!("closure for closure type {:?} not found", data);
@@ -736,7 +736,7 @@ fn closure_fn_trait_impl_datum(
736 736
737 let trait_ref = TraitRef { 737 let trait_ref = TraitRef {
738 trait_, 738 trait_,
739 substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(), 739 substs: Substs::build_for_def(db, trait_.id).push(self_ty).push(arg_ty).build(),
740 }; 740 };
741 741
742 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()).to_chalk(db); 742 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()).to_chalk(db);
@@ -786,7 +786,7 @@ fn type_alias_associated_ty_value(
786 let assoc_ty = trait_ 786 let assoc_ty = trait_
787 .associated_type_by_name(db, &type_alias.name(db)) 787 .associated_type_by_name(db, &type_alias.name(db))
788 .expect("assoc ty value should not exist"); // validated when building the impl data as well 788 .expect("assoc ty value should not exist"); // validated when building the impl data as well
789 let generic_params = impl_block.generic_params(db); 789 let generic_params = db.generic_params(impl_block.id.into());
790 let bound_vars = Substs::bound_vars(&generic_params); 790 let bound_vars = Substs::bound_vars(&generic_params);
791 let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); 791 let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars);
792 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; 792 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
@@ -805,7 +805,7 @@ fn closure_fn_trait_output_assoc_ty_value(
805) -> Arc<AssociatedTyValue<ChalkIr>> { 805) -> Arc<AssociatedTyValue<ChalkIr>> {
806 let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db); 806 let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db);
807 807
808 let num_args: u16 = match &data.def.body(db)[data.expr] { 808 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
809 crate::expr::Expr::Lambda { args, .. } => args.len() as u16, 809 crate::expr::Expr::Lambda { args, .. } => args.len() as u16,
810 _ => { 810 _ => {
811 log::warn!("closure for closure type {:?} not found", data); 811 log::warn!("closure for closure type {:?} not found", data);
@@ -833,9 +833,9 @@ fn closure_fn_trait_output_assoc_ty_value(
833} 833}
834 834
835fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<Trait> { 835fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<Trait> {
836 let target = db.lang_item(krate, fn_trait.lang_item_name().into())?; 836 let target = db.lang_item(krate.crate_id, fn_trait.lang_item_name().into())?;
837 match target { 837 match target {
838 crate::lang_item::LangItemTarget::Trait(t) => Some(t), 838 LangItemTarget::TraitId(t) => Some(t.into()),
839 _ => None, 839 _ => None,
840 } 840 }
841} 841}
@@ -847,38 +847,38 @@ fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId {
847 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } 847 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() }
848} 848}
849 849
850impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { 850impl From<chalk_ir::StructId> for crate::ty::TypeCtorId {
851 fn from(struct_id: chalk_ir::StructId) -> Self { 851 fn from(struct_id: chalk_ir::StructId) -> Self {
852 id_from_chalk(struct_id.0) 852 id_from_chalk(struct_id.0)
853 } 853 }
854} 854}
855 855
856impl From<crate::ids::TypeCtorId> for chalk_ir::StructId { 856impl From<crate::ty::TypeCtorId> for chalk_ir::StructId {
857 fn from(type_ctor_id: crate::ids::TypeCtorId) -> Self { 857 fn from(type_ctor_id: crate::ty::TypeCtorId) -> Self {
858 chalk_ir::StructId(id_to_chalk(type_ctor_id)) 858 chalk_ir::StructId(id_to_chalk(type_ctor_id))
859 } 859 }
860} 860}
861 861
862impl From<chalk_ir::ImplId> for crate::ids::GlobalImplId { 862impl From<chalk_ir::ImplId> for crate::ty::traits::GlobalImplId {
863 fn from(impl_id: chalk_ir::ImplId) -> Self { 863 fn from(impl_id: chalk_ir::ImplId) -> Self {
864 id_from_chalk(impl_id.0) 864 id_from_chalk(impl_id.0)
865 } 865 }
866} 866}
867 867
868impl From<crate::ids::GlobalImplId> for chalk_ir::ImplId { 868impl From<crate::ty::traits::GlobalImplId> for chalk_ir::ImplId {
869 fn from(impl_id: crate::ids::GlobalImplId) -> Self { 869 fn from(impl_id: crate::ty::traits::GlobalImplId) -> Self {
870 chalk_ir::ImplId(id_to_chalk(impl_id)) 870 chalk_ir::ImplId(id_to_chalk(impl_id))
871 } 871 }
872} 872}
873 873
874impl From<chalk_rust_ir::AssociatedTyValueId> for crate::ids::AssocTyValueId { 874impl From<chalk_rust_ir::AssociatedTyValueId> for crate::ty::traits::AssocTyValueId {
875 fn from(id: chalk_rust_ir::AssociatedTyValueId) -> Self { 875 fn from(id: chalk_rust_ir::AssociatedTyValueId) -> Self {
876 id_from_chalk(id.0) 876 id_from_chalk(id.0)
877 } 877 }
878} 878}
879 879
880impl From<crate::ids::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId { 880impl From<crate::ty::traits::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId {
881 fn from(assoc_ty_value_id: crate::ids::AssocTyValueId) -> Self { 881 fn from(assoc_ty_value_id: crate::ty::traits::AssocTyValueId) -> Self {
882 chalk_rust_ir::AssociatedTyValueId(id_to_chalk(assoc_ty_value_id)) 882 chalk_rust_ir::AssociatedTyValueId(id_to_chalk(assoc_ty_value_id))
883 } 883 }
884} 884}
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs
deleted file mode 100644
index 392f244cf..000000000
--- a/crates/ra_hir/src/type_alias.rs
+++ /dev/null
@@ -1,31 +0,0 @@
1//! HIR for type aliases (i.e. the `type` keyword).
2
3use std::sync::Arc;
4
5use hir_def::type_ref::TypeRef;
6use hir_expand::name::{AsName, Name};
7
8use ra_syntax::ast::NameOwner;
9
10use crate::{
11 db::{AstDatabase, DefDatabase},
12 HasSource, TypeAlias,
13};
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct TypeAliasData {
17 pub(crate) name: Name,
18 pub(crate) type_ref: Option<TypeRef>,
19}
20
21impl TypeAliasData {
22 pub(crate) fn type_alias_data_query(
23 db: &(impl DefDatabase + AstDatabase),
24 typ: TypeAlias,
25 ) -> Arc<TypeAliasData> {
26 let node = typ.source(db).value;
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);
29 Arc::new(TypeAliasData { name, type_ref })
30 }
31}