aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--crates/ra_cli/Cargo.toml4
-rw-r--r--crates/ra_cli/src/analysis_stats.rs15
-rw-r--r--crates/ra_hir/src/code_model.rs211
-rw-r--r--crates/ra_hir/src/debug.rs4
-rw-r--r--crates/ra_hir/src/from_id.rs14
-rw-r--r--crates/ra_hir/src/from_source.rs8
-rw-r--r--crates/ra_hir/src/lib.rs7
-rw-r--r--crates/ra_hir/src/source_binder.rs24
-rw-r--r--crates/ra_hir/src/ty.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs206
-rw-r--r--crates/ra_hir_def/src/resolver.rs42
-rw-r--r--crates/ra_hir_ty/src/infer/coerce.rs6
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs37
-rw-r--r--crates/ra_ide/src/parent_module.rs2
-rw-r--r--crates/ra_ide/src/references/search_scope.rs16
-rw-r--r--xtask/src/lib.rs4
17 files changed, 243 insertions, 363 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a95f9139f..d80e58548 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -919,6 +919,8 @@ dependencies = [
919 "ra_batch 0.1.0", 919 "ra_batch 0.1.0",
920 "ra_db 0.1.0", 920 "ra_db 0.1.0",
921 "ra_hir 0.1.0", 921 "ra_hir 0.1.0",
922 "ra_hir_def 0.1.0",
923 "ra_hir_ty 0.1.0",
922 "ra_ide 0.1.0", 924 "ra_ide 0.1.0",
923 "ra_prof 0.1.0", 925 "ra_prof 0.1.0",
924 "ra_syntax 0.1.0", 926 "ra_syntax 0.1.0",
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml
index 21a37c7bf..12af075f7 100644
--- a/crates/ra_cli/Cargo.toml
+++ b/crates/ra_cli/Cargo.toml
@@ -12,7 +12,9 @@ env_logger = { version = "0.7.1", default-features = false, features = ["humanti
12ra_syntax = { path = "../ra_syntax" } 12ra_syntax = { path = "../ra_syntax" }
13ra_ide = { path = "../ra_ide" } 13ra_ide = { path = "../ra_ide" }
14ra_batch = { path = "../ra_batch" } 14ra_batch = { path = "../ra_batch" }
15ra_hir = { path = "../ra_hir" } 15hir = { path = "../ra_hir", package = "ra_hir" }
16hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
17hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
16ra_db = { path = "../ra_db" } 18ra_db = { path = "../ra_db" }
17 19
18[dependencies.ra_prof] 20[dependencies.ra_prof]
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs
index 9b1802a5f..ac65415a5 100644
--- a/crates/ra_cli/src/analysis_stats.rs
+++ b/crates/ra_cli/src/analysis_stats.rs
@@ -2,8 +2,13 @@
2 2
3use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; 3use std::{collections::HashSet, fmt::Write, path::Path, time::Instant};
4 4
5use hir::{
6 db::{DefDatabase, HirDatabase},
7 AssocItem, Crate, HasSource, HirDisplay, ModuleDef,
8};
9use hir_def::FunctionId;
10use hir_ty::{Ty, TypeWalk};
5use ra_db::SourceDatabaseExt; 11use ra_db::SourceDatabaseExt;
6use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk};
7use ra_syntax::AstNode; 12use ra_syntax::AstNode;
8 13
9use crate::{progress_report::ProgressReport, Result, Verbosity}; 14use crate::{progress_report::ProgressReport, Result, Verbosity};
@@ -101,8 +106,9 @@ pub fn run(
101 continue; 106 continue;
102 } 107 }
103 } 108 }
104 let body = f.body(db); 109 let f_id = FunctionId::from(f);
105 let inference_result = f.infer(db); 110 let body = db.body(f_id.into());
111 let inference_result = db.infer(f_id.into());
106 for (expr_id, _) in body.exprs.iter() { 112 for (expr_id, _) in body.exprs.iter() {
107 let ty = &inference_result[expr_id]; 113 let ty = &inference_result[expr_id];
108 num_exprs += 1; 114 num_exprs += 1;
@@ -122,7 +128,8 @@ pub fn run(
122 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { 128 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) {
123 num_type_mismatches += 1; 129 num_type_mismatches += 1;
124 if verbosity.is_verbose() { 130 if verbosity.is_verbose() {
125 let src = f.body_source_map(db).expr_syntax(expr_id); 131 let (_, sm) = db.body_with_source_map(f_id.into());
132 let src = sm.expr_syntax(expr_id);
126 if let Some(src) = src { 133 if let Some(src) = src {
127 // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly 134 // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly
128 let original_file = src.file_id.original_file(db); 135 let original_file = src.file_id.original_file(db);
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 4578a0ba8..7ac1bf461 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -7,7 +7,6 @@ use std::sync::Arc;
7use either::Either; 7use either::Either;
8use hir_def::{ 8use hir_def::{
9 adt::VariantData, 9 adt::VariantData,
10 body::{Body, BodySourceMap},
11 builtin_type::BuiltinType, 10 builtin_type::BuiltinType,
12 docs::Documentation, 11 docs::Documentation,
13 expr::{BindingAnnotation, Pat, PatId}, 12 expr::{BindingAnnotation, Pat, PatId},
@@ -24,14 +23,15 @@ use hir_expand::{
24 name::{self, AsName}, 23 name::{self, AsName},
25 MacroDefId, 24 MacroDefId,
26}; 25};
27use hir_ty::expr::ExprValidator; 26use hir_ty::{
28use ra_db::{CrateId, Edition}; 27 autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment,
28 TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk,
29};
30use ra_db::{CrateId, Edition, FileId};
29use ra_syntax::ast; 31use ra_syntax::ast;
30 32
31use crate::{ 33use crate::{
32 db::{DefDatabase, HirDatabase}, 34 db::{DefDatabase, HirDatabase},
33 ty::display::HirFormatter,
34 ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk},
35 CallableDef, HirDisplay, InFile, Name, 35 CallableDef, HirDisplay, InFile, Name,
36}; 36};
37 37
@@ -40,7 +40,7 @@ use crate::{
40/// root module. 40/// root module.
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
42pub struct Crate { 42pub struct Crate {
43 pub(crate) crate_id: CrateId, 43 pub(crate) id: CrateId,
44} 44}
45 45
46#[derive(Debug)] 46#[derive(Debug)]
@@ -50,33 +50,43 @@ pub struct CrateDependency {
50} 50}
51 51
52impl Crate { 52impl Crate {
53 pub fn crate_id(self) -> CrateId {
54 self.crate_id
55 }
56
57 pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> { 53 pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> {
58 db.crate_graph() 54 db.crate_graph()
59 .dependencies(self.crate_id) 55 .dependencies(self.id)
60 .map(|dep| { 56 .map(|dep| {
61 let krate = Crate { crate_id: dep.crate_id() }; 57 let krate = Crate { id: dep.crate_id() };
62 let name = dep.as_name(); 58 let name = dep.as_name();
63 CrateDependency { krate, name } 59 CrateDependency { krate, name }
64 }) 60 })
65 .collect() 61 .collect()
66 } 62 }
67 63
64 // FIXME: add `transitive_reverse_dependencies`.
65 pub fn reverse_dependencies(self, db: &impl DefDatabase) -> Vec<Crate> {
66 let crate_graph = db.crate_graph();
67 crate_graph
68 .iter()
69 .filter(|&krate| crate_graph.dependencies(krate).any(|it| it.crate_id == self.id))
70 .map(|id| Crate { id })
71 .collect()
72 }
73
68 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { 74 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> {
69 let module_id = db.crate_def_map(self.crate_id).root; 75 let module_id = db.crate_def_map(self.id).root;
70 Some(Module::new(self, module_id)) 76 Some(Module::new(self, module_id))
71 } 77 }
72 78
79 pub fn root_file(self, db: &impl DefDatabase) -> FileId {
80 db.crate_graph().crate_root(self.id)
81 }
82
73 pub fn edition(self, db: &impl DefDatabase) -> Edition { 83 pub fn edition(self, db: &impl DefDatabase) -> Edition {
74 let crate_graph = db.crate_graph(); 84 let crate_graph = db.crate_graph();
75 crate_graph.edition(self.crate_id) 85 crate_graph.edition(self.id)
76 } 86 }
77 87
78 pub fn all(db: &impl DefDatabase) -> Vec<Crate> { 88 pub fn all(db: &impl DefDatabase) -> Vec<Crate> {
79 db.crate_graph().iter().map(|crate_id| Crate { crate_id }).collect() 89 db.crate_graph().iter().map(|id| Crate { id }).collect()
80 } 90 }
81} 91}
82 92
@@ -115,7 +125,7 @@ pub use hir_def::attr::Attrs;
115 125
116impl Module { 126impl Module {
117 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { 127 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
118 Module { id: ModuleId { krate: krate.crate_id, local_id: crate_module_id } } 128 Module { id: ModuleId { krate: krate.id, local_id: crate_module_id } }
119 } 129 }
120 130
121 /// Name of this module. 131 /// Name of this module.
@@ -133,7 +143,7 @@ impl Module {
133 143
134 /// Returns the crate this module is part of. 144 /// Returns the crate this module is part of.
135 pub fn krate(self) -> Crate { 145 pub fn krate(self) -> Crate {
136 Crate { crate_id: self.id.krate } 146 Crate { id: self.id.krate }
137 } 147 }
138 148
139 /// Topmost parent of this module. Every module has a `crate_root`, but some 149 /// Topmost parent of this module. Every module has a `crate_root`, but some
@@ -144,13 +154,6 @@ impl Module {
144 self.with_module_id(def_map.root) 154 self.with_module_id(def_map.root)
145 } 155 }
146 156
147 /// Finds a child module with the specified name.
148 pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> {
149 let def_map = db.crate_def_map(self.id.krate);
150 let child_id = def_map[self.id.local_id].children.get(name)?;
151 Some(self.with_module_id(*child_id))
152 }
153
154 /// Iterates over all child modules. 157 /// Iterates over all child modules.
155 pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { 158 pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
156 let def_map = db.crate_def_map(self.id.krate); 159 let def_map = db.crate_def_map(self.id.krate);
@@ -224,7 +227,7 @@ impl Module {
224 def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() 227 def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect()
225 } 228 }
226 229
227 fn with_module_id(self, module_id: LocalModuleId) -> Module { 230 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module {
228 Module::new(self.krate(), module_id) 231 Module::new(self.krate(), module_id)
229 } 232 }
230} 233}
@@ -251,8 +254,10 @@ impl StructField {
251 self.parent.variant_data(db).fields()[self.id].name.clone() 254 self.parent.variant_data(db).fields()[self.id].name.clone()
252 } 255 }
253 256
254 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 257 pub fn ty(&self, db: &impl HirDatabase) -> Type {
255 db.field_types(self.parent.into())[self.id].clone() 258 let var_id = self.parent.into();
259 let ty = db.field_types(var_id)[self.id].clone();
260 Type::new(db, self.parent.module(db).id.krate.into(), var_id, ty)
256 } 261 }
257 262
258 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { 263 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef {
@@ -287,23 +292,10 @@ impl Struct {
287 .collect() 292 .collect()
288 } 293 }
289 294
290 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
291 db.struct_data(self.id.into())
292 .variant_data
293 .fields()
294 .iter()
295 .find(|(_id, data)| data.name == *name)
296 .map(|(id, _)| StructField { parent: self.into(), id })
297 }
298
299 pub fn ty(self, db: &impl HirDatabase) -> Type { 295 pub fn ty(self, db: &impl HirDatabase) -> Type {
300 Type::from_def(db, self.id.module(db).krate, self.id) 296 Type::from_def(db, self.id.module(db).krate, self.id)
301 } 297 }
302 298
303 pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty {
304 db.value_ty(self.id.into())
305 }
306
307 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 299 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
308 db.struct_data(self.id.into()).variant_data.clone() 300 db.struct_data(self.id.into()).variant_data.clone()
309 } 301 }
@@ -336,15 +328,6 @@ impl Union {
336 .collect() 328 .collect()
337 } 329 }
338 330
339 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
340 db.union_data(self.id)
341 .variant_data
342 .fields()
343 .iter()
344 .find(|(_id, data)| data.name == *name)
345 .map(|(id, _)| StructField { parent: self.into(), id })
346 }
347
348 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 331 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
349 db.union_data(self.id).variant_data.clone() 332 db.union_data(self.id).variant_data.clone()
350 } 333 }
@@ -376,11 +359,6 @@ impl Enum {
376 .collect() 359 .collect()
377 } 360 }
378 361
379 pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
380 let id = db.enum_data(self.id).variant(name)?;
381 Some(EnumVariant { parent: self, id })
382 }
383
384 pub fn ty(self, db: &impl HirDatabase) -> Type { 362 pub fn ty(self, db: &impl HirDatabase) -> Type {
385 Type::from_def(db, self.id.module(db).krate, self.id) 363 Type::from_def(db, self.id.module(db).krate, self.id)
386 } 364 }
@@ -412,14 +390,6 @@ impl EnumVariant {
412 .collect() 390 .collect()
413 } 391 }
414 392
415 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
416 self.variant_data(db)
417 .fields()
418 .iter()
419 .find(|(_id, data)| data.name == *name)
420 .map(|(id, _)| StructField { parent: self.into(), id })
421 }
422
423 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 393 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
424 db.enum_data(self.parent.id).variants[self.id].variant_data.clone() 394 db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
425 } 395 }
@@ -537,48 +507,8 @@ impl Function {
537 db.function_data(self.id).params.clone() 507 db.function_data(self.id).params.clone()
538 } 508 }
539 509
540 pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
541 db.body_with_source_map(self.id.into()).1
542 }
543
544 pub fn body(self, db: &impl HirDatabase) -> Arc<Body> {
545 db.body(self.id.into())
546 }
547
548 pub fn ty(self, db: &impl HirDatabase) -> Ty {
549 db.value_ty(self.id.into())
550 }
551
552 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
553 db.infer(self.id.into())
554 }
555
556 /// The containing impl block, if this is a method.
557 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
558 match self.container(db) {
559 Some(Container::ImplBlock(it)) => Some(it),
560 _ => None,
561 }
562 }
563
564 /// The containing trait, if this is a trait method definition.
565 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
566 match self.container(db) {
567 Some(Container::Trait(it)) => Some(it),
568 _ => None,
569 }
570 }
571
572 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
573 match self.id.lookup(db).container {
574 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
575 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
576 ContainerId::ModuleId(_) => None,
577 }
578 }
579
580 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { 510 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
581 let infer = self.infer(db); 511 let infer = db.infer(self.id.into());
582 infer.add_diagnostics(db, self.id, sink); 512 infer.add_diagnostics(db, self.id, sink);
583 let mut validator = ExprValidator::new(self.id, infer, sink); 513 let mut validator = ExprValidator::new(self.id, infer, sink);
584 validator.validate_body(db); 514 validator.validate_body(db);
@@ -603,10 +533,6 @@ impl Const {
603 db.const_data(self.id).name.clone() 533 db.const_data(self.id).name.clone()
604 } 534 }
605 535
606 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
607 db.infer(self.id.into())
608 }
609
610 /// The containing impl block, if this is a type alias. 536 /// The containing impl block, if this is a type alias.
611 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { 537 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
612 match self.container(db) { 538 match self.container(db) {
@@ -645,10 +571,6 @@ impl Static {
645 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 571 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
646 Some(self.module(db).krate()) 572 Some(self.module(db).krate())
647 } 573 }
648
649 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
650 db.infer(self.id.into())
651 }
652} 574}
653 575
654#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 576#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -763,15 +685,6 @@ impl AssocItem {
763 AssocItem::TypeAlias(t) => t.module(db), 685 AssocItem::TypeAlias(t) => t.module(db),
764 } 686 }
765 } 687 }
766
767 pub fn container(self, db: &impl DefDatabase) -> Container {
768 match self {
769 AssocItem::Function(f) => f.container(db),
770 AssocItem::Const(c) => c.container(db),
771 AssocItem::TypeAlias(t) => t.container(db),
772 }
773 .expect("AssocItem without container")
774 }
775} 688}
776 689
777#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 690#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
@@ -878,11 +791,11 @@ pub struct ImplBlock {
878 791
879impl ImplBlock { 792impl ImplBlock {
880 pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { 793 pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> {
881 let impls = db.impls_in_crate(krate.crate_id); 794 let impls = db.impls_in_crate(krate.id);
882 impls.all_impls().map(Self::from).collect() 795 impls.all_impls().map(Self::from).collect()
883 } 796 }
884 pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { 797 pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> {
885 let impls = db.impls_in_crate(krate.crate_id); 798 let impls = db.impls_in_crate(krate.id);
886 impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() 799 impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect()
887 } 800 }
888 801
@@ -915,7 +828,7 @@ impl ImplBlock {
915 } 828 }
916 829
917 pub fn krate(&self, db: &impl DefDatabase) -> Crate { 830 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
918 Crate { crate_id: self.module(db).id.krate } 831 Crate { id: self.module(db).id.krate }
919 } 832 }
920} 833}
921 834
@@ -926,15 +839,19 @@ pub struct Type {
926} 839}
927 840
928impl Type { 841impl Type {
842 fn new(db: &impl HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
843 let resolver = lexical_env.resolver(db);
844 let environment = TraitEnvironment::lower(db, &resolver);
845 Type { krate, ty: InEnvironment { value: ty, environment } }
846 }
847
929 fn from_def( 848 fn from_def(
930 db: &impl HirDatabase, 849 db: &impl HirDatabase,
931 krate: CrateId, 850 krate: CrateId,
932 def: impl HasResolver + Into<TyDefId>, 851 def: impl HasResolver + Into<TyDefId>,
933 ) -> Type { 852 ) -> Type {
934 let resolver = def.resolver(db);
935 let environment = TraitEnvironment::lower(db, &resolver);
936 let ty = db.ty(def.into()); 853 let ty = db.ty(def.into());
937 Type { krate, ty: InEnvironment { value: ty, environment } } 854 Type::new(db, krate, def, ty)
938 } 855 }
939 856
940 pub fn is_bool(&self) -> bool { 857 pub fn is_bool(&self) -> bool {
@@ -984,7 +901,7 @@ impl Type {
984 pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { 901 pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> {
985 if let Ty::Apply(a_ty) = &self.ty.value { 902 if let Ty::Apply(a_ty) = &self.ty.value {
986 match a_ty.ctor { 903 match a_ty.ctor {
987 ty::TypeCtor::Adt(AdtId::StructId(s)) => { 904 TypeCtor::Adt(AdtId::StructId(s)) => {
988 let var_def = s.into(); 905 let var_def = s.into();
989 return db 906 return db
990 .field_types(var_def) 907 .field_types(var_def)
@@ -1006,7 +923,7 @@ impl Type {
1006 let mut res = Vec::new(); 923 let mut res = Vec::new();
1007 if let Ty::Apply(a_ty) = &self.ty.value { 924 if let Ty::Apply(a_ty) = &self.ty.value {
1008 match a_ty.ctor { 925 match a_ty.ctor {
1009 ty::TypeCtor::Tuple { .. } => { 926 TypeCtor::Tuple { .. } => {
1010 for ty in a_ty.parameters.iter() { 927 for ty in a_ty.parameters.iter() {
1011 let ty = ty.clone().subst(&a_ty.parameters); 928 let ty = ty.clone().subst(&a_ty.parameters);
1012 res.push(self.derived(ty)); 929 res.push(self.derived(ty));
@@ -1025,11 +942,16 @@ impl Type {
1025 ) -> Vec<(StructField, Type)> { 942 ) -> Vec<(StructField, Type)> {
1026 // FIXME: check that ty and def match 943 // FIXME: check that ty and def match
1027 match &self.ty.value { 944 match &self.ty.value {
1028 Ty::Apply(a_ty) => def 945 Ty::Apply(a_ty) => {
1029 .fields(db) 946 let field_types = db.field_types(def.into());
1030 .into_iter() 947 def.fields(db)
1031 .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters)))) 948 .into_iter()
1032 .collect(), 949 .map(|it| {
950 let ty = field_types[it.id].clone().subst(&a_ty.parameters);
951 (it, self.derived(ty))
952 })
953 .collect()
954 }
1033 _ => Vec::new(), 955 _ => Vec::new(),
1034 } 956 }
1035 } 957 }
@@ -1037,10 +959,10 @@ impl Type {
1037 pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { 959 pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a {
1038 // There should be no inference vars in types passed here 960 // There should be no inference vars in types passed here
1039 // FIXME check that? 961 // FIXME check that?
1040 let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 }; 962 let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 };
1041 let environment = self.ty.environment.clone(); 963 let environment = self.ty.environment.clone();
1042 let ty = InEnvironment { value: canonical, environment: environment.clone() }; 964 let ty = InEnvironment { value: canonical, environment: environment.clone() };
1043 ty::autoderef(db, Some(self.krate), ty) 965 autoderef(db, Some(self.krate), ty)
1044 .map(|canonical| canonical.value) 966 .map(|canonical| canonical.value)
1045 .map(move |ty| self.derived(ty)) 967 .map(move |ty| self.derived(ty))
1046 } 968 }
@@ -1053,7 +975,7 @@ impl Type {
1053 krate: Crate, 975 krate: Crate,
1054 mut callback: impl FnMut(AssocItem) -> Option<T>, 976 mut callback: impl FnMut(AssocItem) -> Option<T>,
1055 ) -> Option<T> { 977 ) -> Option<T> {
1056 for krate in self.ty.value.def_crates(db, krate.crate_id)? { 978 for krate in self.ty.value.def_crates(db, krate.id)? {
1057 let impls = db.impls_in_crate(krate); 979 let impls = db.impls_in_crate(krate);
1058 980
1059 for impl_block in impls.lookup_impl_blocks(&self.ty.value) { 981 for impl_block in impls.lookup_impl_blocks(&self.ty.value) {
@@ -1080,15 +1002,14 @@ impl Type {
1080 // FIXME: provide required accessors such that it becomes implementable from outside. 1002 // FIXME: provide required accessors such that it becomes implementable from outside.
1081 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { 1003 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1082 match (&self.ty.value, &other.ty.value) { 1004 match (&self.ty.value, &other.ty.value) {
1083 (Ty::Apply(a_original_ty), Ty::Apply(ty::ApplicationTy { ctor, parameters })) => { 1005 (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor
1084 match ctor { 1006 {
1085 TypeCtor::Ref(..) => match parameters.as_single() { 1007 TypeCtor::Ref(..) => match parameters.as_single() {
1086 Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, 1008 Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor,
1087 _ => false, 1009 _ => false,
1088 }, 1010 },
1089 _ => a_original_ty.ctor == *ctor, 1011 _ => a_original_ty.ctor == *ctor,
1090 } 1012 },
1091 }
1092 _ => false, 1013 _ => false,
1093 } 1014 }
1094 } 1015 }
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs
index 7a2810f71..6cd5c8cb9 100644
--- a/crates/ra_hir/src/debug.rs
+++ b/crates/ra_hir/src/debug.rs
@@ -57,9 +57,9 @@ pub trait HirDebugDatabase {
57impl<DB: HirDebugHelper> HirDebugDatabase for DB { 57impl<DB: HirDebugHelper> HirDebugDatabase for DB {
58 fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 58 fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
59 let mut builder = fmt.debug_tuple("Crate"); 59 let mut builder = fmt.debug_tuple("Crate");
60 match self.crate_name(krate.crate_id) { 60 match self.crate_name(krate.id) {
61 Some(name) => builder.field(&name), 61 Some(name) => builder.field(&name),
62 None => builder.field(&krate.crate_id), 62 None => builder.field(&krate.id),
63 } 63 }
64 .finish() 64 .finish()
65 } 65 }
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs
index e96a18d12..75a1a7772 100644
--- a/crates/ra_hir/src/from_id.rs
+++ b/crates/ra_hir/src/from_id.rs
@@ -9,16 +9,10 @@ use hir_def::{
9}; 9};
10 10
11use crate::{ 11use crate::{
12 Adt, AssocItem, AttrDef, Crate, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField, 12 Adt, AssocItem, AttrDef, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField,
13 VariantDef, 13 VariantDef,
14}; 14};
15 15
16impl From<ra_db::CrateId> for Crate {
17 fn from(crate_id: ra_db::CrateId) -> Self {
18 Crate { crate_id }
19 }
20}
21
22macro_rules! from_id { 16macro_rules! from_id {
23 ($(($id:path, $ty:path)),*) => {$( 17 ($(($id:path, $ty:path)),*) => {$(
24 impl From<$id> for $ty { 18 impl From<$id> for $ty {
@@ -26,10 +20,16 @@ macro_rules! from_id {
26 $ty { id } 20 $ty { id }
27 } 21 }
28 } 22 }
23 impl From<$ty> for $id {
24 fn from(ty: $ty) -> $id {
25 ty.id
26 }
27 }
29 )*} 28 )*}
30} 29}
31 30
32from_id![ 31from_id![
32 (ra_db::CrateId, crate::Crate),
33 (hir_def::ModuleId, crate::Module), 33 (hir_def::ModuleId, crate::Module),
34 (hir_def::StructId, crate::Struct), 34 (hir_def::StructId, crate::Struct),
35 (hir_def::UnionId, crate::Union), 35 (hir_def::UnionId, crate::Union),
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 4acc038e4..307f3d5bf 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -95,7 +95,7 @@ impl FromSource for MacroDef {
95 95
96 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); 96 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
97 let module = Module::from_definition(db, InFile::new(src.file_id, module_src))?; 97 let module = Module::from_definition(db, InFile::new(src.file_id, module_src))?;
98 let krate = Some(module.krate().crate_id()); 98 let krate = Some(module.krate().id);
99 99
100 let ast_id = Some(AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value))); 100 let ast_id = Some(AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value)));
101 101
@@ -216,8 +216,10 @@ impl Module {
216 } 216 }
217 }?; 217 }?;
218 218
219 let child_name = src.value.name()?; 219 let child_name = src.value.name()?.as_name();
220 parent_module.child(db, &child_name.as_name()) 220 let def_map = db.crate_def_map(parent_module.id.krate);
221 let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?;
222 Some(parent_module.with_module_id(*child_id))
221 } 223 }
222 224
223 pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> { 225 pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 9eb34b5dc..bb22882b1 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -31,7 +31,6 @@ pub mod debug;
31pub mod db; 31pub mod db;
32pub mod source_binder; 32pub mod source_binder;
33 33
34mod ty;
35pub mod diagnostics; 34pub mod diagnostics;
36 35
37mod from_id; 36mod from_id;
@@ -48,11 +47,6 @@ pub use crate::{
48 }, 47 },
49 from_source::FromSource, 48 from_source::FromSource,
50 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, 49 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
51 ty::{
52 display::HirDisplay,
53 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain},
54 ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
55 },
56}; 50};
57 51
58pub use hir_def::{ 52pub use hir_def::{
@@ -66,3 +60,4 @@ pub use hir_def::{
66pub use hir_expand::{ 60pub use hir_expand::{
67 name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, 61 name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile,
68}; 62};
63pub use hir_ty::{display::HirDisplay, CallableDef};
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index c5a920688..9efd0477c 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -22,6 +22,10 @@ use hir_def::{
22use hir_expand::{ 22use hir_expand::{
23 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, 23 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
24}; 24};
25use hir_ty::{
26 method_resolution::{self, implements_trait},
27 Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty,
28};
25use ra_syntax::{ 29use ra_syntax::{
26 ast::{self, AstNode}, 30 ast::{self, AstNode},
27 match_ast, AstPtr, 31 match_ast, AstPtr,
@@ -30,13 +34,9 @@ use ra_syntax::{
30}; 34};
31 35
32use crate::{ 36use crate::{
33 db::HirDatabase, 37 db::HirDatabase, Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function,
34 ty::{ 38 ImplBlock, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias,
35 method_resolution::{self, implements_trait}, 39 TypeParam,
36 InEnvironment, TraitEnvironment, Ty,
37 },
38 Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, ImplBlock, Local,
39 MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam,
40}; 40};
41 41
42fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> { 42fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> {
@@ -100,7 +100,7 @@ pub struct SourceAnalyzer {
100 resolver: Resolver, 100 resolver: Resolver,
101 body_owner: Option<DefWithBody>, 101 body_owner: Option<DefWithBody>,
102 body_source_map: Option<Arc<BodySourceMap>>, 102 body_source_map: Option<Arc<BodySourceMap>>,
103 infer: Option<Arc<crate::ty::InferenceResult>>, 103 infer: Option<Arc<InferenceResult>>,
104 scopes: Option<Arc<ExprScopes>>, 104 scopes: Option<Arc<ExprScopes>>,
105} 105}
106 106
@@ -376,7 +376,7 @@ impl SourceAnalyzer {
376 // There should be no inference vars in types passed here 376 // There should be no inference vars in types passed here
377 // FIXME check that? 377 // FIXME check that?
378 // FIXME replace Unknown by bound vars here 378 // FIXME replace Unknown by bound vars here
379 let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; 379 let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
380 method_resolution::iterate_method_candidates( 380 method_resolution::iterate_method_candidates(
381 &canonical, 381 &canonical,
382 db, 382 db,
@@ -400,7 +400,7 @@ impl SourceAnalyzer {
400 // There should be no inference vars in types passed here 400 // There should be no inference vars in types passed here
401 // FIXME check that? 401 // FIXME check that?
402 // FIXME replace Unknown by bound vars here 402 // FIXME replace Unknown by bound vars here
403 let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; 403 let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
404 method_resolution::iterate_method_candidates( 404 method_resolution::iterate_method_candidates(
405 &canonical, 405 &canonical,
406 db, 406 db,
@@ -418,7 +418,7 @@ impl SourceAnalyzer {
418 // ) -> impl Iterator<Item = Ty> + 'a { 418 // ) -> impl Iterator<Item = Ty> + 'a {
419 // // There should be no inference vars in types passed here 419 // // There should be no inference vars in types passed here
420 // // FIXME check that? 420 // // FIXME check that?
421 // let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; 421 // let canonical = Canonical { value: ty, num_vars: 0 };
422 // let krate = self.resolver.krate(); 422 // let krate = self.resolver.krate();
423 // let environment = TraitEnvironment::lower(db, &self.resolver); 423 // let environment = TraitEnvironment::lower(db, &self.resolver);
424 // let ty = crate::ty::InEnvironment { value: canonical, environment }; 424 // let ty = crate::ty::InEnvironment { value: canonical, environment };
@@ -440,7 +440,7 @@ impl SourceAnalyzer {
440 _ => return false, 440 _ => return false,
441 }; 441 };
442 442
443 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; 443 let canonical_ty = Canonical { value: ty, num_vars: 0 };
444 implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) 444 implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait)
445 } 445 }
446 446
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
deleted file mode 100644
index 4ed69c00d..000000000
--- a/crates/ra_hir/src/ty.rs
+++ /dev/null
@@ -1,4 +0,0 @@
1//! The type system. We currently use this to infer types for completion, hover
2//! information and various assists.
3
4pub use hir_ty::*;
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 3ff071f9e..a80067979 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -12,7 +12,7 @@ use hir_expand::{
12use ra_cfg::CfgOptions; 12use ra_cfg::CfgOptions;
13use ra_db::{CrateId, FileId}; 13use ra_db::{CrateId, FileId};
14use ra_syntax::ast; 14use ra_syntax::ast;
15use rustc_hash::{FxHashMap, FxHashSet}; 15use rustc_hash::FxHashMap;
16use test_utils::tested_by; 16use test_utils::tested_by;
17 17
18use crate::{ 18use crate::{
@@ -63,42 +63,12 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
63 unexpanded_macros: Vec::new(), 63 unexpanded_macros: Vec::new(),
64 unexpanded_attribute_macros: Vec::new(), 64 unexpanded_attribute_macros: Vec::new(),
65 mod_dirs: FxHashMap::default(), 65 mod_dirs: FxHashMap::default(),
66 macro_stack_monitor: MacroStackMonitor::default(),
67 poison_macros: FxHashSet::default(),
68 cfg_options, 66 cfg_options,
69 }; 67 };
70 collector.collect(); 68 collector.collect();
71 collector.finish() 69 collector.finish()
72} 70}
73 71
74#[derive(Default)]
75struct MacroStackMonitor {
76 counts: FxHashMap<MacroDefId, u32>,
77
78 /// Mainly use for test
79 validator: Option<Box<dyn Fn(u32) -> bool>>,
80}
81
82impl MacroStackMonitor {
83 fn increase(&mut self, macro_def_id: MacroDefId) {
84 *self.counts.entry(macro_def_id).or_default() += 1;
85 }
86
87 fn decrease(&mut self, macro_def_id: MacroDefId) {
88 *self.counts.entry(macro_def_id).or_default() -= 1;
89 }
90
91 fn is_poison(&self, macro_def_id: MacroDefId) -> bool {
92 let cur = *self.counts.get(&macro_def_id).unwrap_or(&0);
93
94 if let Some(validator) = &self.validator {
95 validator(cur)
96 } else {
97 cur > 100
98 }
99 }
100}
101
102#[derive(Copy, Clone, Debug, Eq, PartialEq)] 72#[derive(Copy, Clone, Debug, Eq, PartialEq)]
103enum PartialResolvedImport { 73enum PartialResolvedImport {
104 /// None of any namespaces is resolved 74 /// None of any namespaces is resolved
@@ -127,6 +97,14 @@ struct ImportDirective {
127 status: PartialResolvedImport, 97 status: PartialResolvedImport,
128} 98}
129 99
100#[derive(Clone, Debug, Eq, PartialEq)]
101struct MacroDirective {
102 module_id: LocalModuleId,
103 ast_id: AstId<ast::MacroCall>,
104 path: Path,
105 legacy: Option<MacroCallId>,
106}
107
130/// Walks the tree of module recursively 108/// Walks the tree of module recursively
131struct DefCollector<'a, DB> { 109struct DefCollector<'a, DB> {
132 db: &'a DB, 110 db: &'a DB,
@@ -134,25 +112,9 @@ struct DefCollector<'a, DB> {
134 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>, 112 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>,
135 unresolved_imports: Vec<ImportDirective>, 113 unresolved_imports: Vec<ImportDirective>,
136 resolved_imports: Vec<ImportDirective>, 114 resolved_imports: Vec<ImportDirective>,
137 unexpanded_macros: Vec<(LocalModuleId, AstId<ast::MacroCall>, Path)>, 115 unexpanded_macros: Vec<MacroDirective>,
138 unexpanded_attribute_macros: Vec<(LocalModuleId, AstId<ast::ModuleItem>, Path)>, 116 unexpanded_attribute_macros: Vec<(LocalModuleId, AstId<ast::ModuleItem>, Path)>,
139 mod_dirs: FxHashMap<LocalModuleId, ModDir>, 117 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
140
141 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly
142 /// To prevent stack overflow, we add a deep counter here for prevent that.
143 macro_stack_monitor: MacroStackMonitor,
144 /// Some macros are not well-behavior, which leads to infinite loop
145 /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } }
146 /// We mark it down and skip it in collector
147 ///
148 /// FIXME:
149 /// Right now it only handle a poison macro in a single crate,
150 /// such that if other crate try to call that macro,
151 /// the whole process will do again until it became poisoned in that crate.
152 /// We should handle this macro set globally
153 /// However, do we want to put it as a global variable?
154 poison_macros: FxHashSet<MacroDefId>,
155
156 cfg_options: &'a CfgOptions, 118 cfg_options: &'a CfgOptions,
157} 119}
158 120
@@ -556,18 +518,24 @@ where
556 std::mem::replace(&mut self.unexpanded_attribute_macros, Vec::new()); 518 std::mem::replace(&mut self.unexpanded_attribute_macros, Vec::new());
557 let mut resolved = Vec::new(); 519 let mut resolved = Vec::new();
558 let mut res = ReachedFixedPoint::Yes; 520 let mut res = ReachedFixedPoint::Yes;
559 macros.retain(|(module_id, ast_id, path)| { 521 macros.retain(|directive| {
522 if let Some(call_id) = directive.legacy {
523 res = ReachedFixedPoint::No;
524 resolved.push((directive.module_id, call_id));
525 return false;
526 }
527
560 let resolved_res = self.def_map.resolve_path_fp_with_macro( 528 let resolved_res = self.def_map.resolve_path_fp_with_macro(
561 self.db, 529 self.db,
562 ResolveMode::Other, 530 ResolveMode::Other,
563 *module_id, 531 directive.module_id,
564 path, 532 &directive.path,
565 BuiltinShadowMode::Module, 533 BuiltinShadowMode::Module,
566 ); 534 );
567 535
568 if let Some(def) = resolved_res.resolved_def.take_macros() { 536 if let Some(def) = resolved_res.resolved_def.take_macros() {
569 let call_id = def.as_call_id(self.db, MacroCallKind::FnLike(*ast_id)); 537 let call_id = def.as_call_id(self.db, MacroCallKind::FnLike(directive.ast_id));
570 resolved.push((*module_id, call_id, def)); 538 resolved.push((directive.module_id, call_id));
571 res = ReachedFixedPoint::No; 539 res = ReachedFixedPoint::No;
572 return false; 540 return false;
573 } 541 }
@@ -579,7 +547,7 @@ where
579 547
580 if let Some(def) = resolved_res { 548 if let Some(def) = resolved_res {
581 let call_id = def.as_call_id(self.db, MacroCallKind::Attr(*ast_id)); 549 let call_id = def.as_call_id(self.db, MacroCallKind::Attr(*ast_id));
582 resolved.push((*module_id, call_id, def)); 550 resolved.push((*module_id, call_id));
583 res = ReachedFixedPoint::No; 551 res = ReachedFixedPoint::No;
584 return false; 552 return false;
585 } 553 }
@@ -590,8 +558,8 @@ where
590 self.unexpanded_macros = macros; 558 self.unexpanded_macros = macros;
591 self.unexpanded_attribute_macros = attribute_macros; 559 self.unexpanded_attribute_macros = attribute_macros;
592 560
593 for (module_id, macro_call_id, macro_def_id) in resolved { 561 for (module_id, macro_call_id) in resolved {
594 self.collect_macro_expansion(module_id, macro_call_id, macro_def_id); 562 self.collect_macro_expansion(module_id, macro_call_id);
595 } 563 }
596 564
597 res 565 res
@@ -611,36 +579,18 @@ where
611 None 579 None
612 } 580 }
613 581
614 fn collect_macro_expansion( 582 fn collect_macro_expansion(&mut self, module_id: LocalModuleId, macro_call_id: MacroCallId) {
615 &mut self, 583 let file_id: HirFileId = macro_call_id.as_file();
616 module_id: LocalModuleId, 584 let raw_items = self.db.raw_items(file_id);
617 macro_call_id: MacroCallId, 585 let mod_dir = self.mod_dirs[&module_id].clone();
618 macro_def_id: MacroDefId, 586 ModCollector {
619 ) { 587 def_collector: &mut *self,
620 if self.poison_macros.contains(&macro_def_id) { 588 file_id,
621 return; 589 module_id,
622 } 590 raw_items: &raw_items,
623 591 mod_dir,
624 self.macro_stack_monitor.increase(macro_def_id);
625
626 if !self.macro_stack_monitor.is_poison(macro_def_id) {
627 let file_id: HirFileId = macro_call_id.as_file();
628 let raw_items = self.db.raw_items(file_id);
629 let mod_dir = self.mod_dirs[&module_id].clone();
630 ModCollector {
631 def_collector: &mut *self,
632 file_id,
633 module_id,
634 raw_items: &raw_items,
635 mod_dir,
636 }
637 .collect(raw_items.items());
638 } else {
639 log::error!("Too deep macro expansion: {:?}", macro_call_id);
640 self.poison_macros.insert(macro_def_id);
641 } 592 }
642 593 .collect(raw_items.items());
643 self.macro_stack_monitor.decrease(macro_def_id);
644 } 594 }
645 595
646 fn finish(self) -> CrateDefMap { 596 fn finish(self) -> CrateDefMap {
@@ -908,15 +858,20 @@ where
908 return; 858 return;
909 } 859 }
910 860
911 // Case 2: try to resolve in legacy scope and expand macro_rules, triggering 861 // Case 2: try to resolve in legacy scope and expand macro_rules
912 // recursive item collection.
913 if let Some(macro_def) = mac.path.as_ident().and_then(|name| { 862 if let Some(macro_def) = mac.path.as_ident().and_then(|name| {
914 self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) 863 self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name)
915 }) { 864 }) {
916 let macro_call_id = 865 let macro_call_id =
917 macro_def.as_call_id(self.def_collector.db, MacroCallKind::FnLike(ast_id)); 866 macro_def.as_call_id(self.def_collector.db, MacroCallKind::FnLike(ast_id));
918 867
919 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_def); 868 self.def_collector.unexpanded_macros.push(MacroDirective {
869 module_id: self.module_id,
870 path: mac.path.clone(),
871 ast_id,
872 legacy: Some(macro_call_id),
873 });
874
920 return; 875 return;
921 } 876 }
922 877
@@ -926,7 +881,13 @@ where
926 if path.is_ident() { 881 if path.is_ident() {
927 path.kind = PathKind::Self_; 882 path.kind = PathKind::Self_;
928 } 883 }
929 self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path)); 884
885 self.def_collector.unexpanded_macros.push(MacroDirective {
886 module_id: self.module_id,
887 path,
888 ast_id,
889 legacy: None,
890 });
930 } 891 }
931 892
932 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { 893 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
@@ -951,19 +912,13 @@ fn is_macro_rules(path: &Path) -> bool {
951 912
952#[cfg(test)] 913#[cfg(test)]
953mod tests { 914mod tests {
915 use crate::{db::DefDatabase, test_db::TestDB};
954 use ra_arena::Arena; 916 use ra_arena::Arena;
955 use ra_db::{fixture::WithFixture, SourceDatabase}; 917 use ra_db::{fixture::WithFixture, SourceDatabase};
956 use rustc_hash::FxHashSet;
957
958 use crate::{db::DefDatabase, test_db::TestDB};
959 918
960 use super::*; 919 use super::*;
961 920
962 fn do_collect_defs( 921 fn do_collect_defs(db: &impl DefDatabase, def_map: CrateDefMap) -> CrateDefMap {
963 db: &impl DefDatabase,
964 def_map: CrateDefMap,
965 monitor: MacroStackMonitor,
966 ) -> (CrateDefMap, FxHashSet<MacroDefId>) {
967 let mut collector = DefCollector { 922 let mut collector = DefCollector {
968 db, 923 db,
969 def_map, 924 def_map,
@@ -973,19 +928,13 @@ mod tests {
973 unexpanded_macros: Vec::new(), 928 unexpanded_macros: Vec::new(),
974 unexpanded_attribute_macros: Vec::new(), 929 unexpanded_attribute_macros: Vec::new(),
975 mod_dirs: FxHashMap::default(), 930 mod_dirs: FxHashMap::default(),
976 macro_stack_monitor: monitor,
977 poison_macros: FxHashSet::default(),
978 cfg_options: &CfgOptions::default(), 931 cfg_options: &CfgOptions::default(),
979 }; 932 };
980 collector.collect(); 933 collector.collect();
981 (collector.def_map, collector.poison_macros) 934 collector.def_map
982 } 935 }
983 936
984 fn do_limited_resolve( 937 fn do_resolve(code: &str) -> CrateDefMap {
985 code: &str,
986 limit: u32,
987 poison_limit: u32,
988 ) -> (CrateDefMap, FxHashSet<MacroDefId>) {
989 let (db, _file_id) = TestDB::with_single_file(&code); 938 let (db, _file_id) = TestDB::with_single_file(&code);
990 let krate = db.test_crate(); 939 let krate = db.test_crate();
991 940
@@ -1003,59 +952,18 @@ mod tests {
1003 diagnostics: Vec::new(), 952 diagnostics: Vec::new(),
1004 } 953 }
1005 }; 954 };
1006 955 do_collect_defs(&db, def_map)
1007 let mut monitor = MacroStackMonitor::default();
1008 monitor.validator = Some(Box::new(move |count| {
1009 assert!(count < limit);
1010 count >= poison_limit
1011 }));
1012
1013 do_collect_defs(&db, def_map, monitor)
1014 } 956 }
1015 957
1016 #[test] 958 #[test]
1017 fn test_macro_expand_limit_width() { 959 fn test_macro_expand_will_stop() {
1018 do_limited_resolve( 960 do_resolve(
1019 r#" 961 r#"
1020 macro_rules! foo { 962 macro_rules! foo {
1021 ($($ty:ty)*) => { foo!($($ty)*, $($ty)*); } 963 ($($ty:ty)*) => { foo!($($ty)*, $($ty)*); }
1022 } 964 }
1023foo!(KABOOM); 965foo!(KABOOM);
1024 "#, 966 "#,
1025 16,
1026 1000,
1027 ); 967 );
1028 } 968 }
1029
1030 #[test]
1031 fn test_macro_expand_poisoned() {
1032 let (_, poison_macros) = do_limited_resolve(
1033 r#"
1034 macro_rules! foo {
1035 ($ty:ty) => { foo!($ty); }
1036 }
1037foo!(KABOOM);
1038 "#,
1039 100,
1040 16,
1041 );
1042
1043 assert_eq!(poison_macros.len(), 1);
1044 }
1045
1046 #[test]
1047 fn test_macro_expand_normal() {
1048 let (_, poison_macros) = do_limited_resolve(
1049 r#"
1050 macro_rules! foo {
1051 ($ident:ident) => { struct $ident {} }
1052 }
1053foo!(Bar);
1054 "#,
1055 16,
1056 16,
1057 );
1058
1059 assert_eq!(poison_macros.len(), 0);
1060 }
1061} 969}
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 4c859e497..9484a61d5 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -19,7 +19,7 @@ use crate::{
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, 20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
21 GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, 21 GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId,
22 StructId, TraitId, TypeAliasId, TypeParamId, 22 StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
23}; 23};
24 24
25#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -544,16 +544,6 @@ impl HasResolver for FunctionId {
544 } 544 }
545} 545}
546 546
547impl HasResolver for DefWithBodyId {
548 fn resolver(self, db: &impl DefDatabase) -> Resolver {
549 match self {
550 DefWithBodyId::ConstId(c) => c.resolver(db),
551 DefWithBodyId::FunctionId(f) => f.resolver(db),
552 DefWithBodyId::StaticId(s) => s.resolver(db),
553 }
554 }
555}
556
557impl HasResolver for ConstId { 547impl HasResolver for ConstId {
558 fn resolver(self, db: &impl DefDatabase) -> Resolver { 548 fn resolver(self, db: &impl DefDatabase) -> Resolver {
559 self.lookup(db).container.resolver(db) 549 self.lookup(db).container.resolver(db)
@@ -572,6 +562,25 @@ impl HasResolver for TypeAliasId {
572 } 562 }
573} 563}
574 564
565impl HasResolver for ImplId {
566 fn resolver(self, db: &impl DefDatabase) -> Resolver {
567 self.module(db)
568 .resolver(db)
569 .push_generic_params_scope(db, self.into())
570 .push_impl_block_scope(self)
571 }
572}
573
574impl HasResolver for DefWithBodyId {
575 fn resolver(self, db: &impl DefDatabase) -> Resolver {
576 match self {
577 DefWithBodyId::ConstId(c) => c.resolver(db),
578 DefWithBodyId::FunctionId(f) => f.resolver(db),
579 DefWithBodyId::StaticId(s) => s.resolver(db),
580 }
581 }
582}
583
575impl HasResolver for ContainerId { 584impl HasResolver for ContainerId {
576 fn resolver(self, db: &impl DefDatabase) -> Resolver { 585 fn resolver(self, db: &impl DefDatabase) -> Resolver {
577 match self { 586 match self {
@@ -596,11 +605,12 @@ impl HasResolver for GenericDefId {
596 } 605 }
597} 606}
598 607
599impl HasResolver for ImplId { 608impl HasResolver for VariantId {
600 fn resolver(self, db: &impl DefDatabase) -> Resolver { 609 fn resolver(self, db: &impl DefDatabase) -> Resolver {
601 self.module(db) 610 match self {
602 .resolver(db) 611 VariantId::EnumVariantId(it) => it.parent.resolver(db),
603 .push_generic_params_scope(db, self.into()) 612 VariantId::StructId(it) => it.resolver(db),
604 .push_impl_block_scope(self) 613 VariantId::UnionId(it) => it.resolver(db),
614 }
605 } 615 }
606} 616}
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs
index 9daa77cfa..0f4dac45e 100644
--- a/crates/ra_hir_ty/src/infer/coerce.rs
+++ b/crates/ra_hir_ty/src/infer/coerce.rs
@@ -332,7 +332,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
332 // It will not recurse to `coerce`. 332 // It will not recurse to `coerce`.
333 return self.table.unify_substs(st1, st2, 0); 333 return self.table.unify_substs(st1, st2, 0);
334 } 334 }
335 _ => {} 335 _ => {
336 if self.table.unify_inner_trivial(&derefed_ty, &to_ty) {
337 return true;
338 }
339 }
336 } 340 }
337 } 341 }
338 342
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index 58b22396f..ac9e3872a 100644
--- a/crates/ra_hir_ty/src/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
@@ -403,3 +403,40 @@ fn test() {
403 "### 403 "###
404 ); 404 );
405} 405}
406
407#[test]
408fn coerce_autoderef_generic() {
409 assert_snapshot!(
410 infer_with_mismatches(r#"
411struct Foo;
412fn takes_ref<T>(x: &T) -> T { *x }
413fn test() {
414 takes_ref(&Foo);
415 takes_ref(&&Foo);
416 takes_ref(&&&Foo);
417}
418"#, true),
419 @r###"
420 [29; 30) 'x': &T
421 [41; 47) '{ *x }': T
422 [43; 45) '*x': T
423 [44; 45) 'x': &T
424 [58; 127) '{ ...oo); }': ()
425 [64; 73) 'takes_ref': fn takes_ref<Foo>(&T) -> T
426 [64; 79) 'takes_ref(&Foo)': Foo
427 [74; 78) '&Foo': &Foo
428 [75; 78) 'Foo': Foo
429 [85; 94) 'takes_ref': fn takes_ref<&Foo>(&T) -> T
430 [85; 101) 'takes_...&&Foo)': &Foo
431 [95; 100) '&&Foo': &&Foo
432 [96; 100) '&Foo': &Foo
433 [97; 100) 'Foo': Foo
434 [107; 116) 'takes_ref': fn takes_ref<&&Foo>(&T) -> T
435 [107; 124) 'takes_...&&Foo)': &&Foo
436 [117; 123) '&&&Foo': &&&Foo
437 [118; 123) '&&Foo': &&Foo
438 [119; 123) '&Foo': &Foo
439 [120; 123) 'Foo': Foo
440 "###
441 );
442}
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs
index aef3fa3df..f5a788c07 100644
--- a/crates/ra_ide/src/parent_module.rs
+++ b/crates/ra_ide/src/parent_module.rs
@@ -30,7 +30,7 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
30 None => return Vec::new(), 30 None => return Vec::new(),
31 }; 31 };
32 let krate = module.krate(); 32 let krate = module.krate();
33 vec![krate.crate_id()] 33 vec![krate.into()]
34} 34}
35 35
36#[cfg(test)] 36#[cfg(test)]
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs
index f5c9589f4..241dd358f 100644
--- a/crates/ra_ide/src/references/search_scope.rs
+++ b/crates/ra_ide/src/references/search_scope.rs
@@ -5,7 +5,7 @@
5use std::mem; 5use std::mem;
6 6
7use hir::{DefWithBody, HasSource, ModuleSource}; 7use hir::{DefWithBody, HasSource, ModuleSource};
8use ra_db::{FileId, SourceDatabase, SourceDatabaseExt}; 8use ra_db::{FileId, SourceDatabaseExt};
9use ra_prof::profile; 9use ra_prof::profile;
10use ra_syntax::{AstNode, TextRange}; 10use ra_syntax::{AstNode, TextRange};
11use rustc_hash::FxHashMap; 11use rustc_hash::FxHashMap;
@@ -120,15 +120,11 @@ impl NameDefinition {
120 } 120 }
121 if vis.as_str() == "pub" { 121 if vis.as_str() == "pub" {
122 let krate = self.container.krate(); 122 let krate = self.container.krate();
123 let crate_graph = db.crate_graph(); 123 for rev_dep in krate.reverse_dependencies(db) {
124 for crate_id in crate_graph.iter() { 124 let root_file = rev_dep.root_file(db);
125 let mut crate_deps = crate_graph.dependencies(crate_id); 125 let source_root_id = db.file_source_root(root_file);
126 if crate_deps.any(|dep| dep.crate_id() == krate.crate_id()) { 126 let source_root = db.source_root(source_root_id);
127 let root_file = crate_graph.crate_root(crate_id); 127 res.extend(source_root.walk().map(|id| (id, None)));
128 let source_root_id = db.file_source_root(root_file);
129 let source_root = db.source_root(source_root_id);
130 res.extend(source_root.walk().map(|id| (id, None)));
131 }
132 } 128 }
133 return SearchScope::new(res); 129 return SearchScope::new(res);
134 } 130 }
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 7332a4072..190baeddf 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -79,7 +79,7 @@ pub fn run_rustfmt(mode: Mode) -> Result<()> {
79} 79}
80 80
81pub fn install_rustfmt() -> Result<()> { 81pub fn install_rustfmt() -> Result<()> {
82 run(&format!("rustup install {}", TOOLCHAIN), ".")?; 82 run(&format!("rustup toolchain install {}", TOOLCHAIN), ".")?;
83 run(&format!("rustup component add rustfmt --toolchain {}", TOOLCHAIN), ".") 83 run(&format!("rustup component add rustfmt --toolchain {}", TOOLCHAIN), ".")
84} 84}
85 85
@@ -125,7 +125,7 @@ pub fn run_clippy() -> Result<()> {
125} 125}
126 126
127pub fn install_clippy() -> Result<()> { 127pub fn install_clippy() -> Result<()> {
128 run(&format!("rustup install {}", TOOLCHAIN), ".")?; 128 run(&format!("rustup toolchain install {}", TOOLCHAIN), ".")?;
129 run(&format!("rustup component add clippy --toolchain {}", TOOLCHAIN), ".") 129 run(&format!("rustup component add clippy --toolchain {}", TOOLCHAIN), ".")
130} 130}
131 131