diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-10 08:50:57 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-10 08:50:57 +0100 |
commit | 37eb12f2dd6f36570a27b4e4aaf9048860b5a06b (patch) | |
tree | f5640991cbf0db2bfdad29b911435827cadfb4a8 | |
parent | b863272899a1bae63c7d9411d0ebff74652bae8e (diff) | |
parent | 10726fdb65fda9144a5f9201272d065a268fc1b7 (diff) |
Merge #1128
1128: A touch of type-safety r=matklad a=matklad
Note that we intentionally don't use `Either` from crates.io: I like A/B naming more then left/rigth, I feel like we might need Either3 with C at some point, and I'd love the ability to write inherent impls
Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/either.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/scope.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_path.rs | 8 | ||||
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 1 | ||||
-rw-r--r-- | crates/ra_ide_api/src/references.rs | 11 |
12 files changed, 85 insertions, 74 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 9e6170440..f13a6b37a 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -4,7 +4,7 @@ use ra_db::{CrateId, SourceRootId, Edition}; | |||
4 | use ra_syntax::{ast::self, TreeArc}; | 4 | use ra_syntax::{ast::self, TreeArc}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | Name, ScopesWithSourceMap, Ty, HirFileId, ImportSource, | 7 | Name, ScopesWithSourceMap, Ty, HirFileId, Either, |
8 | HirDatabase, DefDatabase, | 8 | HirDatabase, DefDatabase, |
9 | type_ref::TypeRef, | 9 | type_ref::TypeRef, |
10 | nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, | 10 | nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, |
@@ -117,8 +117,14 @@ impl Module { | |||
117 | } | 117 | } |
118 | 118 | ||
119 | /// Returns the syntax of the last path segment corresponding to this import | 119 | /// Returns the syntax of the last path segment corresponding to this import |
120 | pub fn import_source(&self, db: &impl HirDatabase, import: ImportId) -> ImportSource { | 120 | pub fn import_source( |
121 | self.import_source_impl(db, import) | 121 | &self, |
122 | db: &impl HirDatabase, | ||
123 | import: ImportId, | ||
124 | ) -> Either<TreeArc<ast::UseTree>, TreeArc<ast::ExternCrateItem>> { | ||
125 | let (file_id, source) = self.definition_source(db); | ||
126 | let (_, source_map) = db.raw_items_with_source_map(file_id); | ||
127 | source_map.get(&source, import) | ||
122 | } | 128 | } |
123 | 129 | ||
124 | /// Returns the crate this module is part of. | 130 | /// Returns the crate this module is part of. |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 88dee3a69..5c2ea73ce 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -3,9 +3,9 @@ use ra_syntax::{ast, TreeArc}; | |||
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Name, AstId, | 5 | Module, ModuleSource, Name, AstId, |
6 | nameres::{CrateModuleId, ImportId}, | 6 | nameres::CrateModuleId, |
7 | HirDatabase, DefDatabase, | 7 | HirDatabase, DefDatabase, |
8 | HirFileId, ImportSource, | 8 | HirFileId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | impl ModuleSource { | 11 | impl ModuleSource { |
@@ -68,16 +68,6 @@ impl Module { | |||
68 | Some((decl.file_id(), ast)) | 68 | Some((decl.file_id(), ast)) |
69 | } | 69 | } |
70 | 70 | ||
71 | pub(crate) fn import_source_impl( | ||
72 | &self, | ||
73 | db: &impl HirDatabase, | ||
74 | import: ImportId, | ||
75 | ) -> ImportSource { | ||
76 | let (file_id, source) = self.definition_source(db); | ||
77 | let (_, source_map) = db.raw_items_with_source_map(file_id); | ||
78 | source_map.get(&source, import) | ||
79 | } | ||
80 | |||
81 | pub(crate) fn crate_root_impl(&self, db: &impl DefDatabase) -> Module { | 71 | pub(crate) fn crate_root_impl(&self, db: &impl DefDatabase) -> Module { |
82 | let def_map = db.crate_def_map(self.krate); | 72 | let def_map = db.crate_def_map(self.krate); |
83 | self.with_module_id(def_map.root()) | 73 | self.with_module_id(def_map.root()) |
diff --git a/crates/ra_hir/src/either.rs b/crates/ra_hir/src/either.rs new file mode 100644 index 000000000..4073cc82e --- /dev/null +++ b/crates/ra_hir/src/either.rs | |||
@@ -0,0 +1,28 @@ | |||
1 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
2 | pub enum Either<A, B> { | ||
3 | A(A), | ||
4 | B(B), | ||
5 | } | ||
6 | |||
7 | impl<A, B> Either<A, B> { | ||
8 | pub fn either<R, F1, F2>(self, f1: F1, f2: F2) -> R | ||
9 | where | ||
10 | F1: FnOnce(A) -> R, | ||
11 | F2: FnOnce(B) -> R, | ||
12 | { | ||
13 | match self { | ||
14 | Either::A(a) => f1(a), | ||
15 | Either::B(b) => f2(b), | ||
16 | } | ||
17 | } | ||
18 | pub fn map<U, V, F1, F2>(self, f1: F1, f2: F2) -> Either<U, V> | ||
19 | where | ||
20 | F1: FnOnce(A) -> U, | ||
21 | F2: FnOnce(B) -> V, | ||
22 | { | ||
23 | match self { | ||
24 | Either::A(a) => Either::A(f1(a)), | ||
25 | Either::B(b) => Either::B(f2(b)), | ||
26 | } | ||
27 | } | ||
28 | } | ||
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 589a9b2db..a2840c15d 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -10,7 +10,7 @@ use ra_syntax::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Path, Name, HirDatabase, Resolver,DefWithBody, | 13 | Path, Name, HirDatabase, Resolver,DefWithBody, Either, |
14 | name::AsName, | 14 | name::AsName, |
15 | type_ref::{Mutability, TypeRef}, | 15 | type_ref::{Mutability, TypeRef}, |
16 | }; | 16 | }; |
@@ -51,11 +51,13 @@ pub struct Body { | |||
51 | pub struct BodySourceMap { | 51 | pub struct BodySourceMap { |
52 | expr_map: FxHashMap<SyntaxNodePtr, ExprId>, | 52 | expr_map: FxHashMap<SyntaxNodePtr, ExprId>, |
53 | expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, | 53 | expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, |
54 | pat_map: FxHashMap<SyntaxNodePtr, PatId>, | 54 | pat_map: FxHashMap<PatPrr, PatId>, |
55 | pat_map_back: ArenaMap<PatId, SyntaxNodePtr>, | 55 | pat_map_back: ArenaMap<PatId, PatPrr>, |
56 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::NamedField>>, | 56 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::NamedField>>, |
57 | } | 57 | } |
58 | 58 | ||
59 | type PatPrr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; | ||
60 | |||
59 | impl Body { | 61 | impl Body { |
60 | pub fn params(&self) -> &[PatId] { | 62 | pub fn params(&self) -> &[PatId] { |
61 | &self.params | 63 | &self.params |
@@ -127,16 +129,16 @@ impl BodySourceMap { | |||
127 | self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() | 129 | self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
128 | } | 130 | } |
129 | 131 | ||
130 | pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { | 132 | pub fn pat_syntax(&self, pat: PatId) -> Option<PatPrr> { |
131 | self.pat_map_back.get(pat).cloned() | 133 | self.pat_map_back.get(pat).cloned() |
132 | } | 134 | } |
133 | 135 | ||
134 | pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> { | 136 | pub fn syntax_pat(&self, ptr: PatPrr) -> Option<PatId> { |
135 | self.pat_map.get(&ptr).cloned() | 137 | self.pat_map.get(&ptr).cloned() |
136 | } | 138 | } |
137 | 139 | ||
138 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | 140 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
139 | self.pat_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() | 141 | self.pat_map.get(&Either::A(AstPtr::new(node))).cloned() |
140 | } | 142 | } |
141 | 143 | ||
142 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::NamedField> { | 144 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::NamedField> { |
@@ -504,10 +506,10 @@ impl ExprCollector { | |||
504 | id | 506 | id |
505 | } | 507 | } |
506 | 508 | ||
507 | fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId { | 509 | fn alloc_pat(&mut self, pat: Pat, ptr: PatPrr) -> PatId { |
508 | let id = self.pats.alloc(pat); | 510 | let id = self.pats.alloc(pat); |
509 | self.source_map.pat_map.insert(syntax_ptr, id); | 511 | self.source_map.pat_map.insert(ptr, id); |
510 | self.source_map.pat_map_back.insert(id, syntax_ptr); | 512 | self.source_map.pat_map_back.insert(id, ptr); |
511 | id | 513 | id |
512 | } | 514 | } |
513 | 515 | ||
@@ -886,8 +888,8 @@ impl ExprCollector { | |||
886 | ast::PatKind::LiteralPat(_) => Pat::Missing, | 888 | ast::PatKind::LiteralPat(_) => Pat::Missing, |
887 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, | 889 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, |
888 | }; | 890 | }; |
889 | let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); | 891 | let ptr = AstPtr::new(pat); |
890 | self.alloc_pat(pattern, syntax_ptr) | 892 | self.alloc_pat(pattern, Either::A(ptr)) |
891 | } | 893 | } |
892 | 894 | ||
893 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { | 895 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { |
@@ -911,14 +913,14 @@ impl ExprCollector { | |||
911 | fn collect_fn_body(&mut self, node: &ast::FnDef) { | 913 | fn collect_fn_body(&mut self, node: &ast::FnDef) { |
912 | if let Some(param_list) = node.param_list() { | 914 | if let Some(param_list) = node.param_list() { |
913 | if let Some(self_param) = param_list.self_param() { | 915 | if let Some(self_param) = param_list.self_param() { |
914 | let self_param = SyntaxNodePtr::new(self_param.syntax()); | 916 | let ptr = AstPtr::new(self_param); |
915 | let param_pat = self.alloc_pat( | 917 | let param_pat = self.alloc_pat( |
916 | Pat::Bind { | 918 | Pat::Bind { |
917 | name: Name::self_param(), | 919 | name: Name::self_param(), |
918 | mode: BindingAnnotation::Unannotated, | 920 | mode: BindingAnnotation::Unannotated, |
919 | subpat: None, | 921 | subpat: None, |
920 | }, | 922 | }, |
921 | self_param, | 923 | Either::B(ptr), |
922 | ); | 924 | ); |
923 | self.params.push(param_pat); | 925 | self.params.push(param_pat); |
924 | } | 926 | } |
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index f1e6e0f02..725b6c00e 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs | |||
@@ -3,14 +3,14 @@ use std::sync::Arc; | |||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | 4 | ||
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | AstNode, SyntaxNode, TextUnit, TextRange, SyntaxNodePtr, | 6 | AstNode, SyntaxNode, TextUnit, TextRange, SyntaxNodePtr, AstPtr, |
7 | algo::generate, | 7 | algo::generate, |
8 | ast, | 8 | ast, |
9 | }; | 9 | }; |
10 | use ra_arena::{Arena, RawId, impl_arena_id}; | 10 | use ra_arena::{Arena, RawId, impl_arena_id}; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Name, AsName,DefWithBody, | 13 | Name, AsName,DefWithBody, Either, |
14 | expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySourceMap}, | 14 | expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySourceMap}, |
15 | HirDatabase, | 15 | HirDatabase, |
16 | }; | 16 | }; |
@@ -116,7 +116,7 @@ pub struct ScopesWithSourceMap { | |||
116 | #[derive(Debug, Clone, PartialEq, Eq)] | 116 | #[derive(Debug, Clone, PartialEq, Eq)] |
117 | pub struct ScopeEntryWithSyntax { | 117 | pub struct ScopeEntryWithSyntax { |
118 | name: Name, | 118 | name: Name, |
119 | ptr: SyntaxNodePtr, | 119 | ptr: Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>, |
120 | } | 120 | } |
121 | 121 | ||
122 | impl ScopeEntryWithSyntax { | 122 | impl ScopeEntryWithSyntax { |
@@ -124,7 +124,7 @@ impl ScopeEntryWithSyntax { | |||
124 | &self.name | 124 | &self.name |
125 | } | 125 | } |
126 | 126 | ||
127 | pub fn ptr(&self) -> SyntaxNodePtr { | 127 | pub fn ptr(&self) -> Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>> { |
128 | self.ptr | 128 | self.ptr |
129 | } | 129 | } |
130 | } | 130 | } |
@@ -192,14 +192,14 @@ impl ScopesWithSourceMap { | |||
192 | 192 | ||
193 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | 193 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { |
194 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | 194 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); |
195 | let name_ptr = SyntaxNodePtr::new(pat.syntax()); | 195 | let ptr = Either::A(AstPtr::new(pat.into())); |
196 | fn_def | 196 | fn_def |
197 | .syntax() | 197 | .syntax() |
198 | .descendants() | 198 | .descendants() |
199 | .filter_map(ast::NameRef::cast) | 199 | .filter_map(ast::NameRef::cast) |
200 | .filter(|name_ref| match self.resolve_local_name(*name_ref) { | 200 | .filter(|name_ref| match self.resolve_local_name(*name_ref) { |
201 | None => false, | 201 | None => false, |
202 | Some(entry) => entry.ptr() == name_ptr, | 202 | Some(entry) => entry.ptr() == ptr, |
203 | }) | 203 | }) |
204 | .map(|name_ref| ReferenceDescriptor { | 204 | .map(|name_ref| ReferenceDescriptor { |
205 | name: name_ref.syntax().text().to_string(), | 205 | name: name_ref.syntax().text().to_string(), |
@@ -429,7 +429,8 @@ mod tests { | |||
429 | let scopes = | 429 | let scopes = |
430 | ScopesWithSourceMap { scopes: Arc::new(scopes), source_map: Arc::new(source_map) }; | 430 | ScopesWithSourceMap { scopes: Arc::new(scopes), source_map: Arc::new(source_map) }; |
431 | let local_name_entry = scopes.resolve_local_name(name_ref).unwrap(); | 431 | let local_name_entry = scopes.resolve_local_name(name_ref).unwrap(); |
432 | let local_name = local_name_entry.ptr(); | 432 | let local_name = |
433 | local_name_entry.ptr().either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); | ||
433 | assert_eq!(local_name.range(), expected_name.syntax().range()); | 434 | assert_eq!(local_name.range(), expected_name.syntax().range()); |
434 | } | 435 | } |
435 | 436 | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 4d337d2e3..0881939a2 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -17,6 +17,8 @@ macro_rules! impl_froms { | |||
17 | } | 17 | } |
18 | } | 18 | } |
19 | 19 | ||
20 | mod either; | ||
21 | |||
20 | pub mod db; | 22 | pub mod db; |
21 | #[macro_use] | 23 | #[macro_use] |
22 | pub mod mock; | 24 | pub mod mock; |
@@ -52,11 +54,12 @@ use crate::{ | |||
52 | }; | 54 | }; |
53 | 55 | ||
54 | pub use self::{ | 56 | pub use self::{ |
57 | either::Either, | ||
55 | path::{Path, PathKind}, | 58 | path::{Path, PathKind}, |
56 | name::Name, | 59 | name::Name, |
57 | source_id::{AstIdMap, ErasedFileAstId}, | 60 | source_id::{AstIdMap, ErasedFileAstId}, |
58 | ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc}, | 61 | ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc}, |
59 | nameres::{PerNs, Namespace, ImportId, ImportSource}, | 62 | nameres::{PerNs, Namespace, ImportId}, |
60 | ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, | 63 | ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, |
61 | impl_block::{ImplBlock, ImplItem}, | 64 | impl_block::{ImplBlock, ImplItem}, |
62 | docs::{Docs, Documentation}, | 65 | docs::{Docs, Documentation}, |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 4ae04514a..0eddfab12 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -75,7 +75,7 @@ pub(crate) use self::raw::{RawItems, ImportSourceMap}; | |||
75 | 75 | ||
76 | pub use self::{ | 76 | pub use self::{ |
77 | per_ns::{PerNs, Namespace}, | 77 | per_ns::{PerNs, Namespace}, |
78 | raw::{ImportId, ImportSource}, | 78 | raw::ImportId, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /// Contans all top-level defs from a macro-expanded crate | 81 | /// Contans all top-level defs from a macro-expanded crate |
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index b7416ede6..43c97a0bf 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -12,7 +12,7 @@ use ra_syntax::{ | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, | 14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, |
15 | AstIdMap, FileAstId, | 15 | AstIdMap, FileAstId, Either, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | /// `RawItems` is a set of top-level items in a file (except for impls). | 18 | /// `RawItems` is a set of top-level items in a file (except for impls). |
@@ -34,28 +34,15 @@ pub struct ImportSourceMap { | |||
34 | map: ArenaMap<ImportId, ImportSourcePtr>, | 34 | map: ArenaMap<ImportId, ImportSourcePtr>, |
35 | } | 35 | } |
36 | 36 | ||
37 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 37 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; |
38 | enum ImportSourcePtr { | 38 | type ImportSource = Either<TreeArc<ast::UseTree>, TreeArc<ast::ExternCrateItem>>; |
39 | UseTree(AstPtr<ast::UseTree>), | ||
40 | ExternCrate(AstPtr<ast::ExternCrateItem>), | ||
41 | } | ||
42 | 39 | ||
43 | impl ImportSourcePtr { | 40 | impl ImportSourcePtr { |
44 | fn to_node(self, file: &SourceFile) -> ImportSource { | 41 | fn to_node(self, file: &SourceFile) -> ImportSource { |
45 | match self { | 42 | self.map(|ptr| ptr.to_node(file).to_owned(), |ptr| ptr.to_node(file).to_owned()) |
46 | ImportSourcePtr::UseTree(ptr) => ImportSource::UseTree(ptr.to_node(file).to_owned()), | ||
47 | ImportSourcePtr::ExternCrate(ptr) => { | ||
48 | ImportSource::ExternCrate(ptr.to_node(file).to_owned()) | ||
49 | } | ||
50 | } | ||
51 | } | 43 | } |
52 | } | 44 | } |
53 | 45 | ||
54 | pub enum ImportSource { | ||
55 | UseTree(TreeArc<ast::UseTree>), | ||
56 | ExternCrate(TreeArc<ast::ExternCrateItem>), | ||
57 | } | ||
58 | |||
59 | impl ImportSourceMap { | 46 | impl ImportSourceMap { |
60 | fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { | 47 | fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { |
61 | self.map.insert(import, ptr) | 48 | self.map.insert(import, ptr) |
@@ -281,11 +268,7 @@ impl RawItemsCollector { | |||
281 | Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| { | 268 | Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| { |
282 | let import_data = | 269 | let import_data = |
283 | ImportData { path, alias, is_glob, is_prelude, is_extern_crate: false }; | 270 | ImportData { path, alias, is_glob, is_prelude, is_extern_crate: false }; |
284 | self.push_import( | 271 | self.push_import(current_module, import_data, Either::A(AstPtr::new(use_tree))); |
285 | current_module, | ||
286 | import_data, | ||
287 | ImportSourcePtr::UseTree(AstPtr::new(use_tree)), | ||
288 | ); | ||
289 | }) | 272 | }) |
290 | } | 273 | } |
291 | 274 | ||
@@ -304,11 +287,7 @@ impl RawItemsCollector { | |||
304 | is_prelude: false, | 287 | is_prelude: false, |
305 | is_extern_crate: true, | 288 | is_extern_crate: true, |
306 | }; | 289 | }; |
307 | self.push_import( | 290 | self.push_import(current_module, import_data, Either::B(AstPtr::new(extern_crate))); |
308 | current_module, | ||
309 | import_data, | ||
310 | ImportSourcePtr::ExternCrate(AstPtr::new(extern_crate)), | ||
311 | ); | ||
312 | } | 291 | } |
313 | } | 292 | } |
314 | 293 | ||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index f6a325033..ecc63f376 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2324,7 +2324,7 @@ fn infer(content: &str) -> String { | |||
2324 | 2324 | ||
2325 | for (pat, ty) in inference_result.type_of_pat.iter() { | 2325 | for (pat, ty) in inference_result.type_of_pat.iter() { |
2326 | let syntax_ptr = match body_source_map.pat_syntax(pat) { | 2326 | let syntax_ptr = match body_source_map.pat_syntax(pat) { |
2327 | Some(sp) => sp, | 2327 | Some(sp) => sp.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()), |
2328 | None => continue, | 2328 | None => continue, |
2329 | }; | 2329 | }; |
2330 | types.push((syntax_ptr, ty)); | 2330 | types.push((syntax_ptr, ty)); |
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index e54fe7b7e..7e47fa6bd 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use hir::Resolution; | 1 | use hir::{Resolution, Either}; |
2 | use ra_syntax::AstNode; | 2 | use ra_syntax::AstNode; |
3 | use test_utils::tested_by; | 3 | use test_utils::tested_by; |
4 | 4 | ||
@@ -19,10 +19,8 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
19 | for (name, res) in module_scope.entries() { | 19 | for (name, res) in module_scope.entries() { |
20 | if Some(module) == ctx.module { | 20 | if Some(module) == ctx.module { |
21 | if let Some(import) = res.import { | 21 | if let Some(import) = res.import { |
22 | if let hir::ImportSource::UseTree(tree) = | 22 | if let Either::A(use_tree) = module.import_source(ctx.db, import) { |
23 | module.import_source(ctx.db, import) | 23 | if use_tree.syntax().range().contains_inclusive(ctx.offset) { |
24 | { | ||
25 | if tree.syntax().range().contains_inclusive(ctx.offset) { | ||
26 | // for `use self::foo<|>`, don't suggest `foo` as a completion | 24 | // for `use self::foo<|>`, don't suggest `foo` as a completion |
27 | tested_by!(dont_complete_current_use); | 25 | tested_by!(dont_complete_current_use); |
28 | continue; | 26 | continue; |
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 660b43cfa..60c1f5085 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -113,6 +113,7 @@ pub(crate) fn reference_definition( | |||
113 | let ptr = source_map.pat_syntax(pat).expect("pattern not found in syntax mapping"); | 113 | let ptr = source_map.pat_syntax(pat).expect("pattern not found in syntax mapping"); |
114 | let name = | 114 | let name = |
115 | path.as_ident().cloned().expect("local binding from a multi-segment path"); | 115 | path.as_ident().cloned().expect("local binding from a multi-segment path"); |
116 | let ptr = ptr.either(|it| it.into(), |it| it.into()); | ||
116 | let nav = NavigationTarget::from_scope_entry(file_id, name, ptr); | 117 | let nav = NavigationTarget::from_scope_entry(file_id, name, ptr); |
117 | return Exact(nav); | 118 | return Exact(nav); |
118 | } | 119 | } |
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index 20bbf11a3..3e30e047c 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use relative_path::{RelativePath, RelativePathBuf}; | 1 | use relative_path::{RelativePath, RelativePathBuf}; |
2 | use hir::{ModuleSource, source_binder}; | 2 | use hir::{ModuleSource, source_binder, Either}; |
3 | use ra_db::{SourceDatabase}; | 3 | use ra_db::{SourceDatabase}; |
4 | use ra_syntax::{ | 4 | use ra_syntax::{ |
5 | AstNode, SyntaxNode, SourceFile, | 5 | AstNode, SyntaxNode, SourceFile, |
@@ -89,9 +89,12 @@ pub(crate) fn find_all_refs( | |||
89 | source_binder::function_from_child_node(db, position.file_id, name_ref.syntax())?; | 89 | source_binder::function_from_child_node(db, position.file_id, name_ref.syntax())?; |
90 | let scope = descr.scopes(db); | 90 | let scope = descr.scopes(db); |
91 | let resolved = scope.resolve_local_name(name_ref)?; | 91 | let resolved = scope.resolve_local_name(name_ref)?; |
92 | let resolved = resolved.ptr().to_node(source_file); | 92 | if let Either::A(ptr) = resolved.ptr() { |
93 | let binding = find_node_at_offset::<ast::BindPat>(syntax, resolved.range().end())?; | 93 | if let ast::PatKind::BindPat(binding) = ptr.to_node(source_file).kind() { |
94 | Some((binding, descr)) | 94 | return Some((binding, descr)); |
95 | } | ||
96 | } | ||
97 | None | ||
95 | } | 98 | } |
96 | } | 99 | } |
97 | 100 | ||