aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-04-02 11:26:09 +0100
committerAleksey Kladov <[email protected]>2019-04-02 11:26:09 +0100
commit49f13d3a9bb5bf3ab92c3fbf23ad79cb001b76e0 (patch)
tree55a59317e363ba5aa419366643502ce3656e1bb2
parentab19ff16e55d4d64445fc2809e52d913ad492040 (diff)
fix a panic with glob-import missing a source map
-rw-r--r--crates/ra_hir/src/code_model_api.rs6
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs2
-rw-r--r--crates/ra_hir/src/nameres/raw.rs16
-rw-r--r--crates/ra_hir/src/path.rs13
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs12
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)]
33pub struct ImportSourceMap { 33pub struct ImportSourceMap {
34 map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>, 34 map: ArenaMap<ImportId, AstPtr<ast::UseTree>>,
35} 35}
36 36
37impl ImportSourceMap { 37impl 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 {
156fn expand_use_tree<'a>( 156fn 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",