diff options
author | Aleksey Kladov <[email protected]> | 2019-04-02 11:26:09 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-04-02 11:26:09 +0100 |
commit | 49f13d3a9bb5bf3ab92c3fbf23ad79cb001b76e0 (patch) | |
tree | 55a59317e363ba5aa419366643502ce3656e1bb2 | |
parent | ab19ff16e55d4d64445fc2809e52d913ad492040 (diff) |
fix a panic with glob-import missing a source map
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/path.rs | 13 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_path.rs | 12 |
5 files changed, 26 insertions, 23 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 624c25c4d..46455bd83 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -117,11 +117,7 @@ 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( | 120 | pub fn import_source(&self, db: &impl HirDatabase, import: ImportId) -> TreeArc<ast::UseTree> { |
121 | &self, | ||
122 | db: &impl HirDatabase, | ||
123 | import: ImportId, | ||
124 | ) -> TreeArc<ast::PathSegment> { | ||
125 | self.import_source_impl(db, import) | 121 | self.import_source_impl(db, import) |
126 | } | 122 | } |
127 | 123 | ||
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 0edb8ade5..ccca2b7e5 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -72,7 +72,7 @@ impl Module { | |||
72 | &self, | 72 | &self, |
73 | db: &impl HirDatabase, | 73 | db: &impl HirDatabase, |
74 | import: ImportId, | 74 | import: ImportId, |
75 | ) -> TreeArc<ast::PathSegment> { | 75 | ) -> TreeArc<ast::UseTree> { |
76 | let (file_id, source) = self.definition_source(db); | 76 | let (file_id, source) = self.definition_source(db); |
77 | let (_, source_map) = db.raw_items_with_source_map(file_id); | 77 | let (_, source_map) = db.raw_items_with_source_map(file_id); |
78 | source_map.get(&source, import) | 78 | source_map.get(&source, import) |
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 0936229ac..35cbe6655 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -31,15 +31,15 @@ pub struct RawItems { | |||
31 | 31 | ||
32 | #[derive(Debug, Default, PartialEq, Eq)] | 32 | #[derive(Debug, Default, PartialEq, Eq)] |
33 | pub struct ImportSourceMap { | 33 | pub struct ImportSourceMap { |
34 | map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>, | 34 | map: ArenaMap<ImportId, AstPtr<ast::UseTree>>, |
35 | } | 35 | } |
36 | 36 | ||
37 | impl ImportSourceMap { | 37 | impl ImportSourceMap { |
38 | fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { | 38 | fn insert(&mut self, import: ImportId, use_tree: &ast::UseTree) { |
39 | self.map.insert(import, AstPtr::new(segment)) | 39 | self.map.insert(import, AstPtr::new(use_tree)) |
40 | } | 40 | } |
41 | 41 | ||
42 | pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> { | 42 | pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::UseTree> { |
43 | let file = match source { | 43 | let file = match source { |
44 | ModuleSource::SourceFile(file) => &*file, | 44 | ModuleSource::SourceFile(file) => &*file, |
45 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), | 45 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), |
@@ -256,17 +256,15 @@ impl RawItemsCollector { | |||
256 | fn add_use_item(&mut self, current_module: Option<Module>, use_item: &ast::UseItem) { | 256 | fn add_use_item(&mut self, current_module: Option<Module>, use_item: &ast::UseItem) { |
257 | let is_prelude = use_item.has_atom_attr("prelude_import"); | 257 | let is_prelude = use_item.has_atom_attr("prelude_import"); |
258 | 258 | ||
259 | Path::expand_use_item(use_item, |path, segment, alias| { | 259 | Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| { |
260 | let import = self.raw_items.imports.alloc(ImportData { | 260 | let import = self.raw_items.imports.alloc(ImportData { |
261 | path, | 261 | path, |
262 | alias, | 262 | alias, |
263 | is_glob: segment.is_none(), | 263 | is_glob, |
264 | is_prelude, | 264 | is_prelude, |
265 | is_extern_crate: false, | 265 | is_extern_crate: false, |
266 | }); | 266 | }); |
267 | if let Some(segment) = segment { | 267 | self.source_map.insert(import, use_tree); |
268 | self.source_map.insert(import, segment) | ||
269 | } | ||
270 | self.push_item(current_module, RawItem::Import(import)) | 268 | self.push_item(current_module, RawItem::Import(import)) |
271 | }) | 269 | }) |
272 | } | 270 | } |
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index 6cc8104f4..5449cddfd 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -46,7 +46,7 @@ impl Path { | |||
46 | /// Calls `cb` with all paths, represented by this use item. | 46 | /// Calls `cb` with all paths, represented by this use item. |
47 | pub fn expand_use_item<'a>( | 47 | pub fn expand_use_item<'a>( |
48 | item: &'a ast::UseItem, | 48 | item: &'a ast::UseItem, |
49 | mut cb: impl FnMut(Path, Option<&'a ast::PathSegment>, Option<Name>), | 49 | mut cb: impl FnMut(Path, &'a ast::UseTree, bool, Option<Name>), |
50 | ) { | 50 | ) { |
51 | if let Some(tree) = item.use_tree() { | 51 | if let Some(tree) = item.use_tree() { |
52 | expand_use_tree(None, tree, &mut cb); | 52 | expand_use_tree(None, tree, &mut cb); |
@@ -156,7 +156,7 @@ impl From<Name> for Path { | |||
156 | fn expand_use_tree<'a>( | 156 | fn expand_use_tree<'a>( |
157 | prefix: Option<Path>, | 157 | prefix: Option<Path>, |
158 | tree: &'a ast::UseTree, | 158 | tree: &'a ast::UseTree, |
159 | cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>, Option<Name>), | 159 | cb: &mut impl FnMut(Path, &'a ast::UseTree, bool, Option<Name>), |
160 | ) { | 160 | ) { |
161 | if let Some(use_tree_list) = tree.use_tree_list() { | 161 | if let Some(use_tree_list) = tree.use_tree_list() { |
162 | let prefix = match tree.path() { | 162 | let prefix = match tree.path() { |
@@ -181,18 +181,15 @@ fn expand_use_tree<'a>( | |||
181 | if let Some(segment) = ast_path.segment() { | 181 | if let Some(segment) = ast_path.segment() { |
182 | if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { | 182 | if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { |
183 | if let Some(prefix) = prefix { | 183 | if let Some(prefix) = prefix { |
184 | cb(prefix, Some(segment), alias); | 184 | cb(prefix, tree, false, alias); |
185 | return; | 185 | return; |
186 | } | 186 | } |
187 | } | 187 | } |
188 | } | 188 | } |
189 | } | 189 | } |
190 | if let Some(path) = convert_path(prefix, ast_path) { | 190 | if let Some(path) = convert_path(prefix, ast_path) { |
191 | if tree.has_star() { | 191 | let is_glob = tree.has_star(); |
192 | cb(path, None, alias) | 192 | cb(path, tree, is_glob, alias) |
193 | } else if let Some(segment) = ast_path.segment() { | ||
194 | cb(path, Some(segment), alias) | ||
195 | }; | ||
196 | } | 193 | } |
197 | // FIXME: report errors somewhere | 194 | // FIXME: report errors somewhere |
198 | // We get here if we do | 195 | // We get here if we do |
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index 5ff1b9927..122dd7bdd 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -73,6 +73,18 @@ mod tests { | |||
73 | } | 73 | } |
74 | 74 | ||
75 | #[test] | 75 | #[test] |
76 | fn dont_complete_current_use_in_braces_with_glob() { | ||
77 | let completions = do_completion( | ||
78 | r" | ||
79 | mod foo { pub struct S; } | ||
80 | use self::{foo::*, bar<|>}; | ||
81 | ", | ||
82 | CompletionKind::Reference, | ||
83 | ); | ||
84 | assert_eq!(completions.len(), 2); | ||
85 | } | ||
86 | |||
87 | #[test] | ||
76 | fn completes_mod_with_docs() { | 88 | fn completes_mod_with_docs() { |
77 | check_reference_completion( | 89 | check_reference_completion( |
78 | "mod_with_docs", | 90 | "mod_with_docs", |