diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_cli/Cargo.toml | 4 | ||||
-rw-r--r-- | crates/ra_cli/src/analysis_stats.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 211 | ||||
-rw-r--r-- | crates/ra_hir/src/debug.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 206 | ||||
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 42 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 37 | ||||
-rw-r--r-- | crates/ra_ide/src/parent_module.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/references/search_scope.rs | 16 |
15 files changed, 239 insertions, 361 deletions
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 | |||
12 | ra_syntax = { path = "../ra_syntax" } | 12 | ra_syntax = { path = "../ra_syntax" } |
13 | ra_ide = { path = "../ra_ide" } | 13 | ra_ide = { path = "../ra_ide" } |
14 | ra_batch = { path = "../ra_batch" } | 14 | ra_batch = { path = "../ra_batch" } |
15 | ra_hir = { path = "../ra_hir" } | 15 | hir = { path = "../ra_hir", package = "ra_hir" } |
16 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } | ||
17 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | ||
16 | ra_db = { path = "../ra_db" } | 18 | ra_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 | ||
3 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; | 3 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; |
4 | 4 | ||
5 | use hir::{ | ||
6 | db::{DefDatabase, HirDatabase}, | ||
7 | AssocItem, Crate, HasSource, HirDisplay, ModuleDef, | ||
8 | }; | ||
9 | use hir_def::FunctionId; | ||
10 | use hir_ty::{Ty, TypeWalk}; | ||
5 | use ra_db::SourceDatabaseExt; | 11 | use ra_db::SourceDatabaseExt; |
6 | use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; | ||
7 | use ra_syntax::AstNode; | 12 | use ra_syntax::AstNode; |
8 | 13 | ||
9 | use crate::{progress_report::ProgressReport, Result, Verbosity}; | 14 | use 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; | |||
7 | use either::Either; | 7 | use either::Either; |
8 | use hir_def::{ | 8 | use 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 | }; |
27 | use hir_ty::expr::ExprValidator; | 26 | use hir_ty::{ |
28 | use ra_db::{CrateId, Edition}; | 27 | autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment, |
28 | TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, | ||
29 | }; | ||
30 | use ra_db::{CrateId, Edition, FileId}; | ||
29 | use ra_syntax::ast; | 31 | use ra_syntax::ast; |
30 | 32 | ||
31 | use crate::{ | 33 | use 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)] |
42 | pub struct Crate { | 42 | pub 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 | ||
52 | impl Crate { | 52 | impl 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 | ||
116 | impl Module { | 126 | impl 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 | ||
879 | impl ImplBlock { | 792 | impl 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 | ||
928 | impl Type { | 841 | impl 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 { | |||
57 | impl<DB: HirDebugHelper> HirDebugDatabase for DB { | 57 | impl<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 | ||
11 | use crate::{ | 11 | use 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 | ||
16 | impl From<ra_db::CrateId> for Crate { | ||
17 | fn from(crate_id: ra_db::CrateId) -> Self { | ||
18 | Crate { crate_id } | ||
19 | } | ||
20 | } | ||
21 | |||
22 | macro_rules! from_id { | 16 | macro_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 | ||
32 | from_id![ | 31 | from_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; | |||
31 | pub mod db; | 31 | pub mod db; |
32 | pub mod source_binder; | 32 | pub mod source_binder; |
33 | 33 | ||
34 | mod ty; | ||
35 | pub mod diagnostics; | 34 | pub mod diagnostics; |
36 | 35 | ||
37 | mod from_id; | 36 | mod 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 | ||
58 | pub use hir_def::{ | 52 | pub use hir_def::{ |
@@ -66,3 +60,4 @@ pub use hir_def::{ | |||
66 | pub use hir_expand::{ | 60 | pub use hir_expand::{ |
67 | name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, | 61 | name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, |
68 | }; | 62 | }; |
63 | pub 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::{ | |||
22 | use hir_expand::{ | 22 | use hir_expand::{ |
23 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, | 23 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, |
24 | }; | 24 | }; |
25 | use hir_ty::{ | ||
26 | method_resolution::{self, implements_trait}, | ||
27 | Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty, | ||
28 | }; | ||
25 | use ra_syntax::{ | 29 | use 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 | ||
32 | use crate::{ | 36 | use 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 | ||
42 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> { | 42 | fn 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 | |||
4 | pub 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::{ | |||
12 | use ra_cfg::CfgOptions; | 12 | use ra_cfg::CfgOptions; |
13 | use ra_db::{CrateId, FileId}; | 13 | use ra_db::{CrateId, FileId}; |
14 | use ra_syntax::ast; | 14 | use ra_syntax::ast; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::FxHashMap; |
16 | use test_utils::tested_by; | 16 | use test_utils::tested_by; |
17 | 17 | ||
18 | use crate::{ | 18 | use 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)] | ||
75 | struct MacroStackMonitor { | ||
76 | counts: FxHashMap<MacroDefId, u32>, | ||
77 | |||
78 | /// Mainly use for test | ||
79 | validator: Option<Box<dyn Fn(u32) -> bool>>, | ||
80 | } | ||
81 | |||
82 | impl 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(¯o_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)] |
103 | enum PartialResolvedImport { | 73 | enum 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)] | ||
101 | struct 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 |
131 | struct DefCollector<'a, DB> { | 109 | struct 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(¯o_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)] |
953 | mod tests { | 914 | mod 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 | } |
1023 | foo!(KABOOM); | 965 | foo!(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 | } | ||
1037 | foo!(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 | } | ||
1053 | foo!(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 | ||
547 | impl 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 | |||
557 | impl HasResolver for ConstId { | 547 | impl 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 | ||
565 | impl 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 | |||
574 | impl 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 | |||
575 | impl HasResolver for ContainerId { | 584 | impl 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 | ||
599 | impl HasResolver for ImplId { | 608 | impl 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] | ||
408 | fn coerce_autoderef_generic() { | ||
409 | assert_snapshot!( | ||
410 | infer_with_mismatches(r#" | ||
411 | struct Foo; | ||
412 | fn takes_ref<T>(x: &T) -> T { *x } | ||
413 | fn 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 @@ | |||
5 | use std::mem; | 5 | use std::mem; |
6 | 6 | ||
7 | use hir::{DefWithBody, HasSource, ModuleSource}; | 7 | use hir::{DefWithBody, HasSource, ModuleSource}; |
8 | use ra_db::{FileId, SourceDatabase, SourceDatabaseExt}; | 8 | use ra_db::{FileId, SourceDatabaseExt}; |
9 | use ra_prof::profile; | 9 | use ra_prof::profile; |
10 | use ra_syntax::{AstNode, TextRange}; | 10 | use ra_syntax::{AstNode, TextRange}; |
11 | use rustc_hash::FxHashMap; | 11 | use 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 | } |